fix(sandbox): resolve multi-hop symlinks in fs grants - #1776
Open
kipz wants to merge 2 commits into
Open
Conversation
Contributor
PR Review SummarySize
Affected crates
Blast radius — ContainedThis PR touches: source code Updated automatically on each push to this PR. |
kipz
force-pushed
the
kipz/multi-hop-symlink-hops
branch
from
September 3, 2026 13:13
5380b0b to
1514d0b
Compare
kipz
force-pushed
the
kipz/multi-hop-symlink-hops
branch
from
September 3, 2026 13:24
1514d0b to
3e4a21b
Compare
kipz
marked this pull request as ready for review
September 3, 2026 14:28
There was a problem hiding this comment.
nogent code review
No blocking issues; 1 minor performance suggestion.
Findings (not tied to a changed line):
- 🐛 [MEDIUM · bug]
crates/nono/src/sandbox/macos.rs:785— Ingenerate_profile, the path metadata directories loop (caps.path_metadata_dirs()) does not resolve or grantfile-read-metadatato intermediate symlink hops of$PATHdirectories. If any$PATHdirectory (or its parents) uses a multi-hop symlink, command resolution walks inside the sandbox will fail withEPERM(which aborts the$PATHwalk entirely) instead of returningENOENTor succeeding. To resolve this, intermediate symlink hops forpath_metadata_dirsmust also be collected usingcollect_symlink_hopsand grantedfile-read-metadata.
Automated code + security review. CI already covers clippy, rustfmt, tests, cargo-audit and commit-lint.
Signed-off-by: James Carnegie <me@kipz.org>
kipz
force-pushed
the
kipz/multi-hop-symlink-hops
branch
from
September 3, 2026 15:05
3e4a21b to
86734c2
Compare
Signed-off-by: James Carnegie <me@kipz.org>
Contributor
Author
|
Fixed: |
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.
Linked Issue
Closes #1771
Summary
A capability whose path resolves through more than one symlink hop was denied on macOS, even though the final target was already granted. Seatbelt only had rules for the two endpoints (
originaland fully-resolvedresolved), not the intermediate hops the kernel walks through. This adds a bounded hop-enumeration pass and grants each intermediate hopfile-read-metadata, for bothFsCapabilityandUnixSocketCapability. Linux needed no code change, sinceopen_path_ruleresolves the whole chain viaO_PATHbefore Landlock sees a literal path, but a new test verifies that rather than assuming it.Agent Disclosure
This PR was written by an AI coding agent (Claude, via Claude Code) under my direct supervision and review.
Approach: added
collect_symlink_hopsincrates/nono/src/path.rs, walking a path one component at a time and resolving each symlink hop with a bounded depth to avoid cycles. Incrates/nono/src/sandbox/macos.rs, everyFsCapabilityandUnixSocketCapabilitynow also grantsfile-read-metadataon each intermediate hop and its ancestor directories, alongside the existing endpoint rules. No capability schema change, hops are recomputed on demand.Files consulted:
crates/nono/src/path.rs,crates/nono/src/capability.rs,crates/nono/src/sandbox/macos.rs,crates/nono/src/sandbox/linux.rs.Intent and approach were disclosed on the linked issue before implementation: #1771 (comment)
Test Plan
cargo test(workspace): all pass.crates/nono-cli/tests/symlink_hop_run.rs(macOS): new positive and negative cases.crates/nono-cli/tests/symlink_hop_run_linux.rs: same cases, run under real Landlock enforcement. Both pass.make ciclean.Checklist
CHANGELOG.mdif neededAgent Compliance Check