Repository navigation
[Bubblewrap] Mount symlinked grants at their real paths - #1638
Open
Soham Das (SohamDas2021) wants to merge 1 commit into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📖 Description
A
readwritePathsorreadonlyPathsentry named through a symlink was mounted at the path the caller wrote, whiledeniedPathsentries were already moved to their real paths. A denied or read-only path inside such a grant then sat in a different place in the sandbox from the grant, and did not apply to it. For example, with/home/alice/app -> /data/repos/app:.envstayed readable and writable at/home/alice/app/.env. Naming the denial, or areadonlyPathsexception, by its real path under/data/repos/appdid not help: writes through/home/alice/appstill changed the host file.Grants are now mounted at their real paths too, so a grant and the rules inside it sit in one directory tree. Each symlink a grant is named through is recreated inside the sandbox as a relative link, so the caller's spelling still works, including as
process.cwd, and the rules apply under both spellings. In the example, the sandbox mounts/data/repos/app, masks/data/repos/app/.env, and links/home/alice/appto it. This also fixes the case raised in review of #1624: a file granted through/lib, inside a directory denied as/lib/xor/usr/lib/x, is visible again instead of being hidden by the mask.A link the sandbox cannot recreate, such as one under
/devor/proc, or inside a mount of a different host path, leaves that spelling unavailable, and MXC prints a warning naming the real path to use. Where the sandbox has its own directory at the link's path, such as its private/tmpon a host whose/tmplinks to/var/tmp, the next part of the path is linked inside that directory instead, so a grant of/tmp/projectstill works as/tmp/project. A grant that cannot be resolved, such as a dangling symlink or a symlink loop, stops the sandbox from starting, with an error that names the entry.Behavior changes:
Relative entries in
readwritePaths,readonlyPathsanddeniedPathsare resolved from the working directory of the process that starts the sandbox. Before, a relative grant did not appear at the path it names, and a relative denial starting with..masked the wrong file: with/workgranted and/work/subas the working directory,../shared/mmasked/work/sub/shared/mand left/work/shared/mreadable.On a host whose
/tmpis a symlink, a grant of/tmpitself now appears only at its real path, such as/var/tmp. The sandbox keeps its own private/tmp, and MXC prints the warning above.Limitations: only symlinks are followed. A hard link, or a host bind mount that shows the same files under a second path, is still a separate path in the sandbox, so a rule on one does not reach the other (documented). The LXC backend is not covered here and will follow separately.
docs/backends/bwrap/bubblewrap-backend.mdis updated, and the workaround #1624 added there for grants spelled through/libis removed. No spec is needed: this changes how existing filesystem fields are enforced, with no schema or API change.🔗 References
Stacked on #1624; review that first. Security report (reference to be added when published).
🔍 Validation
On WSL Ubuntu 24.04 with bwrap 0.9.0, run unprivileged, and on Windows:
cargo fmt --all -- --check: passedcargo clippy -p mxc-sdk -p lxc --all-targets -- -D warnings(Linux): passedcargo clippy -p mxc-sdk --all-targets -- -D warnings(Windows): passedcargo test -p mxc-sdk --lib -- bubblewrap filesystem_symlink(Linux): 454 passed, 1 failed.probe_exec::tests::a_missing_command_reports_the_spawn_errorfails the same way on [Bubblewrap] Recreate merged-/usr directory symlinks in the sandbox #1624 on this host, because WSL adds Windows directories toPATH, and searching them reports a permission error instead of not-found.cargo test -p mxc-sdk --lib -- bwrap_command(Windows): 73 passedMXC_BWRAP_TESTS_REQUIRE_EXECUTION=1 cargo test -p mxc-sdk --test streaming_bubblewrap: 15 passedMXC_BWRAP_TESTS_REQUIRE_EXECUTION=1 cargo test -p mxc-sdk --test wxc_e2e_tests_e2e_bubblewrap_characterization: 15 passedbash tests/scripts/run_bwrap_grant_alias_test.sh(new, in the nightly Bubblewrap suite): 23 cases passed. On [Bubblewrap] Recreate merged-/usr directory symlinks in the sandbox #1624 it fails: denied files stay readable or writable, and read-only files writable, through the symlinked spelling; a relative denial masks the wrong file; and the/libgrant stays hidden.MXC_BWRAP_TESTS_REQUIRE_EXECUTION=1 bash tests/scripts/run_bwrap_all_tests.sh, with a release build and asudostand-in that runs as WSL's root user: 22 passed, 0 failed, 1 skipped (Inbound Deny, which needs root and is exempt in strict mode)run_bwrap_grant_alias_test.shand [Bubblewrap] Recreate merged-/usr directory symlinks in the sandbox #1624'srun_bwrap_baseline_alias_test.shinside Debian 13, Ubuntu 26.04 and AlmaLinux 10 root filesystems, run under bwrap on the same kernel: passedThe new test covers the cases above in a tmpfs directory and in the home directory, plus chains of links, a link already visible inside another grant, an aliased grant inside a denied directory, dangling and looping grants, and a host whose
/tmpis a symlink, simulated by runninglxc-execinside an outer bwrap. On a host that cannot run bwrap inside bwrap, the script exits 77 at that point, which strict mode reports as a failure.✅ Checklist
feature-acceptedCargo.lock, thedependency-feed-checkcheck passes (see pull request builds)📋 Issue Type
Microsoft Reviewers: Open in CodeFlow