fix: reopen writable linux carveouts under denied parents (#14514)

## Summary
- preserve Linux bubblewrap semantics for `write -> none -> write`
filesystem policies by recreating masked mount targets before rebinding
narrower writable descendants
- add a Linux runtime regression for `/repo = write`, `/repo/a = none`,
`/repo/a/b = write` so the nested writable child is exercised under
bubblewrap
- document the supported legacy Landlock fallback and the split-policy
bubblewrap behavior for overlapping carveouts

## Example
Given a split filesystem policy like:

```toml
"/repo" = "write"
"/repo/a" = "none"
"/repo/a/b" = "write"
```

this PR keeps `/repo` writable, masks `/repo/a`, and still reopens
`/repo/a/b` as writable again under bubblewrap.

## Testing
- `just fmt`
- `cargo test -p codex-linux-sandbox`
- `cargo clippy -p codex-linux-sandbox --tests -- -D warnings`
This commit is contained in:
viyatb-oai
2026-03-12 18:36:06 -07:00
committed by GitHub
parent 7626f61274
commit f194d4b115
4 changed files with 229 additions and 25 deletions

View File

@@ -48,6 +48,18 @@ Seatbelt also supports macOS permission-profile extensions layered on top of
Expects the binary containing `codex-core` to run the equivalent of `codex sandbox linux` (legacy alias: `codex debug landlock`) when `arg0` is `codex-linux-sandbox`. See the `codex-arg0` crate for details.
Legacy `SandboxPolicy` / `sandbox_mode` configs are still supported on Linux.
They can continue to use the legacy Landlock path when the split filesystem
policy is sandbox-equivalent to the legacy model after `cwd` resolution.
Split filesystem policies that need direct `FileSystemSandboxPolicy`
enforcement, such as read-only or denied carveouts under a broader writable
root, automatically route through bubblewrap. The legacy Landlock path is used
only when the split filesystem policy round-trips through the legacy
`SandboxPolicy` model without changing semantics. That includes overlapping
cases like `/repo = write`, `/repo/a = none`, `/repo/a/b = write`, where the
more specific writable child must reopen under a denied parent.
### All Platforms
Expects the binary containing `codex-core` to simulate the virtual `apply_patch` CLI when `arg1` is `--codex-run-as-apply-patch`. See the `codex-arg0` crate for details.