Preserve ENOENT for missing mandatory deny paths#227
Conversation
|
Confirming this resolves the symptom from #139 on my setup. Environment
Symptom beforeEvery sandboxed command bind-mounted git status was also polluted with all of those as untracked entries. They only existed inside the sandbox during command execution (a clean shell never saw them), which matches #139. After applying this PR's logicI backported the diff onto the compiled 0.0.56 dist/ (the source: 'user' | 'mandatory' tagging + skipping placeholder mounts for missing mandatory paths). Missing mandatory paths now stay ENOENT instead of becoming devices/empty dirs: |
Summary
ENOENTfor missing mandatory deny directories instead of mounting/dev/nullor an empty directory over them.denyWritepaths, where they are still needed to block creation..claude/commands.Context
Linux
bwrapcannot express “this path should remain missing, but must not be creatable” with bind mounts alone. The previous implementation used placeholder mounts for missing deny paths. That is still appropriate for explicit userdenyWritepaths, but applying it to mandatory auto-protection changed normal filesystem semantics: missing mandatory directories could appear inside the sandbox as/dev/nullor as an empty directory instead of returningENOENT.This PR skips placeholder mounts for missing mandatory deny paths, matching the documented Linux limitation that mandatory deny protection only applies to paths that already exist.
Tests
npm run typechecknpm run lint:checknpx prettier --check src/sandbox/linux-sandbox-utils.ts test/sandbox/mandatory-deny-paths.test.tsbun test test/sandbox/mandatory-deny-paths.test.tsbun test test/sandbox/wrap-with-sandbox.test.ts test/sandbox/allow-read.test.ts