Skip to content

[WSLC] Add on-disk alias canonicalization to denied-path overlap check#657

Open
SohamDas2021 wants to merge 7 commits into
mainfrom
user/sodas/wslc-alias-canonicalization
Open

[WSLC] Add on-disk alias canonicalization to denied-path overlap check#657
SohamDas2021 wants to merge 7 commits into
mainfrom
user/sodas/wslc-alias-canonicalization

Conversation

@SohamDas2021

@SohamDas2021 SohamDas2021 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

📖 Description

The WSLC denied-path overlap validator was lexical-only: it folded case and ./.. but could not see on-disk aliases (symlinks, junctions, 8.3 short names, \\?\ prefixes), so a deny that resolved into a mounted tree via an alias slipped through and stayed accessible.

Added a shared wxc_common::filesystem_canonical primitive that resolves a path to its canonical DOS form via GetFinalPathNameByHandleW, and wire it into validate_denied_path_overlap as a second tier: after the lexical pre-check, canonicalize every mount and deny, fail closed on any path that exists but cannot be resolved, then re-run the structural
containment compares on the resolved forms.

🔗 References

🔍 Validation

✅ Checklist

📋 Issue Type

  • Bug fix
  • Feature
  • Task

GitHub Actions runs the PR validation build automatically. The ADO pipeline
(MXC-PR-Build) is the Azure version of the PR pipeline, kept in parity with the GitHub
Actions build; it runs on merge to main, and Microsoft reviewers with write access can trigger it
on a PR with /azp run. See docs/pull-requests.md.

If the dependency-feed-check check fails on a new dependency, the crate must be added to
the feed before the PR can pass. See docs/pull-requests.md
for the steps.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@SohamDas2021
SohamDas2021 marked this pull request as ready for review July 16, 2026 23:19
@SohamDas2021
SohamDas2021 requested a review from a team as a code owner July 16, 2026 23:19
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

/// `resolve_through_symlinks`. Returns [`PathCanonical::Absent`] only when no
/// ancestor resolves.
#[cfg(windows)]
pub fn canonicalize_allowing_absent_tail(path: &str) -> PathCanonical {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper handles nonexistent paths by finding the deepest existing ancestor and appending the missing components. While walking backward,  file_name()  returns nothing for  .. , so the algorithm can forget that a preceding component should be cancelled.

For example:

\X\Y..\Z

should normalize to:

\X\Z

but can be reconstructed as:

\X\Y\Z

This matters when    is a junction or other alias. Tier 1 folds  ..  correctly but cannot resolve the alias; Tier 2 resolves the alias but then reconstructs the missing tail incorrectly. It can consequently compare the wrong path and miss a real denied-path overlap.

The fix is to normalize  .  and  ..  before searching for an existing ancestor, or explicitly track parent-component cancellations while building the missing tail. A regression test should combine an aliased ancestor, multiple nonexistent components and  .. .

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixing!

/// window also remains between canonicalization and the SDK mount (an alias
/// could be swapped in between); fully closing it needs handle-based mounting
/// the WSLC SDK does not expose, so it is likewise accepted.
pub fn validate_denied_path_overlap(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR canonicalizes only the paths explicitly listed in the policy. It catches aliases in the mount or deny strings themselves, but not aliases located inside a mounted directory.

Example:

Mounted: C:\project
Denied: C:\secrets
Junction: C:\project\link -> C:\secrets

Canonicalizing the two policy entries produces  C:\project  and  C:\secrets , which do not overlap, so validation succeeds. If WSLC follows the junction inside the mounted tree, the guest can still reach the denied directory through  C:\project\link .

The immediate concern is that the new documentation says canonicalization is “closing the alias gap,” while this gap remains. At minimum, the limitation should be documented precisely. Fully enforcing it would require controlling traversal beneath the mount or inspecting reparse points, which is harder, potentially expensive and still subject to races.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch! I will document this accordingly.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the Needs-Author-Feedback Issue needs attention from issue or PR author label Jul 17, 2026
Base automatically changed from user/sodas/wslc-denied-path-overlap-validation to main July 17, 2026 19:59
@microsoft-github-policy-service microsoft-github-policy-service Bot added Needs-Attention Issue needs attention from Microsoft and removed Needs-Author-Feedback Issue needs attention from issue or PR author labels Jul 17, 2026
@SohamDas2021
SohamDas2021 requested a review from MGudgin July 17, 2026 20:58
@SohamDas2021

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved. The three files with conflicts (policy_mapping.rs, wsl_container_runner.rs, tests/scripts/run_wslc_all_tests.ps1) have been merged with origin/main in commit [Resolve merge conflicts with origin/main]. The two-tier canonicalization implementation and all associated tests are preserved, and the new denied-masking/most-specific test scripts from main are also included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs-Attention Issue needs attention from Microsoft

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants