mirror of
https://github.com/openai/codex.git
synced 2026-04-25 15:15:15 +00:00
linux-sandbox: honor split filesystem policies in bwrap (#13453)
## Why After `#13449`, the Linux helper could receive split filesystem and network policies, but the bubblewrap mount builder still reconstructed filesystem access from the legacy `SandboxPolicy`. That loses explicit unreadable carveouts under writable roots, and it also mishandles `Root` read access paired with explicit deny carveouts. In those cases bubblewrap could still expose paths that the split filesystem policy intentionally blocked. ## What changed - switched bubblewrap mount generation to consume `FileSystemSandboxPolicy` directly at the implementation boundary; legacy `SandboxPolicy` configs still flow through the existing `FileSystemSandboxPolicy::from(&sandbox_policy)` bridge before reaching bwrap - kept the Linux helper and preflight path on the split filesystem policy all the way into bwrap - re-applied explicit unreadable carveouts after readable and writable mounts so blocked subpaths still win under bubblewrap - masked denied directories with `--tmpfs` plus `--remount-ro` and denied files with `--ro-bind-data`, preserving the backing fd until exec - added comments in the unreadable-root masking block to explain why the mount order and directory/file split are intentional - updated Linux helper call sites and tests for the split-policy bwrap path ## Verification - added protocol coverage for root carveouts staying scoped - added core coverage that root-write plus deny carveouts still requires a platform sandbox - added bwrap unit coverage for reapplying blocked carveouts after writable binds - added Linux integration coverage for explicit split-policy carveouts under bubblewrap - validated the final branch state with `cargo test -p codex-linux-sandbox`, `cargo clippy -p codex-linux-sandbox --all-targets -- -D warnings`, and the PR CI reruns --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/13453). * __->__ #13453 * #13452 * #13451 * #13449 * #13448 * #13445 * #13440 * #13439 --------- Co-authored-by: viyatb-oai <viyatb@openai.com>
This commit is contained in:
@@ -35,15 +35,17 @@ fn ignores_non_proc_mount_errors() {
|
||||
|
||||
#[test]
|
||||
fn inserts_bwrap_argv0_before_command_separator() {
|
||||
let sandbox_policy = SandboxPolicy::new_read_only_policy();
|
||||
let argv = build_bwrap_argv(
|
||||
vec!["/bin/true".to_string()],
|
||||
&SandboxPolicy::new_read_only_policy(),
|
||||
&FileSystemSandboxPolicy::from(&sandbox_policy),
|
||||
Path::new("/"),
|
||||
BwrapOptions {
|
||||
mount_proc: true,
|
||||
network_mode: BwrapNetworkMode::FullAccess,
|
||||
},
|
||||
);
|
||||
)
|
||||
.args;
|
||||
assert_eq!(
|
||||
argv,
|
||||
vec![
|
||||
@@ -69,29 +71,33 @@ fn inserts_bwrap_argv0_before_command_separator() {
|
||||
|
||||
#[test]
|
||||
fn inserts_unshare_net_when_network_isolation_requested() {
|
||||
let sandbox_policy = SandboxPolicy::new_read_only_policy();
|
||||
let argv = build_bwrap_argv(
|
||||
vec!["/bin/true".to_string()],
|
||||
&SandboxPolicy::new_read_only_policy(),
|
||||
&FileSystemSandboxPolicy::from(&sandbox_policy),
|
||||
Path::new("/"),
|
||||
BwrapOptions {
|
||||
mount_proc: true,
|
||||
network_mode: BwrapNetworkMode::Isolated,
|
||||
},
|
||||
);
|
||||
)
|
||||
.args;
|
||||
assert!(argv.contains(&"--unshare-net".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inserts_unshare_net_when_proxy_only_network_mode_requested() {
|
||||
let sandbox_policy = SandboxPolicy::new_read_only_policy();
|
||||
let argv = build_bwrap_argv(
|
||||
vec!["/bin/true".to_string()],
|
||||
&SandboxPolicy::new_read_only_policy(),
|
||||
&FileSystemSandboxPolicy::from(&sandbox_policy),
|
||||
Path::new("/"),
|
||||
BwrapOptions {
|
||||
mount_proc: true,
|
||||
network_mode: BwrapNetworkMode::ProxyOnly,
|
||||
},
|
||||
);
|
||||
)
|
||||
.args;
|
||||
assert!(argv.contains(&"--unshare-net".to_string()));
|
||||
}
|
||||
|
||||
@@ -104,7 +110,12 @@ fn proxy_only_mode_takes_precedence_over_full_network_policy() {
|
||||
#[test]
|
||||
fn managed_proxy_preflight_argv_is_wrapped_for_full_access_policy() {
|
||||
let mode = bwrap_network_mode(NetworkSandboxPolicy::Enabled, true);
|
||||
let argv = build_preflight_bwrap_argv(Path::new("/"), &SandboxPolicy::DangerFullAccess, mode);
|
||||
let argv = build_preflight_bwrap_argv(
|
||||
Path::new("/"),
|
||||
&FileSystemSandboxPolicy::from(&SandboxPolicy::DangerFullAccess),
|
||||
mode,
|
||||
)
|
||||
.args;
|
||||
assert!(argv.iter().any(|arg| arg == "--"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user