diff --git a/codex-rs/linux-sandbox/src/linux_run_main.rs b/codex-rs/linux-sandbox/src/linux_run_main.rs index 346b1f14c0..f0b90c2b15 100644 --- a/codex-rs/linux-sandbox/src/linux_run_main.rs +++ b/codex-rs/linux-sandbox/src/linux_run_main.rs @@ -27,7 +27,11 @@ use crate::proxy_routing::activate_proxy_routes_in_netns; use crate::proxy_routing::prepare_host_proxy_route_spec; use codex_protocol::error::Result as CodexResult; use codex_protocol::models::PermissionProfile; +use codex_protocol::protocol::FileSystemAccessMode; +use codex_protocol::protocol::FileSystemPath; +use codex_protocol::protocol::FileSystemSandboxEntry; use codex_protocol::protocol::FileSystemSandboxPolicy; +use codex_protocol::protocol::FileSystemSpecialPath; use codex_protocol::protocol::NetworkSandboxPolicy; use codex_sandboxing::landlock::CODEX_LINUX_SANDBOX_ARG0; @@ -328,13 +332,8 @@ fn run_bwrap_with_proc_fallback( let command_cwd = command_cwd.unwrap_or(sandbox_policy_cwd); if mount_proc - && !preflight_proc_mount_support( - sandbox_policy_cwd, - command_cwd, - file_system_sandbox_policy, - network_mode, - ) - .unwrap_or_else(|err| exit_with_bwrap_build_error(err)) + && !preflight_proc_mount_support(network_mode) + .unwrap_or_else(|err| exit_with_bwrap_build_error(err)) { // Keep the retry silent so sandbox-internal diagnostics do not leak into the // child process stderr stream. @@ -441,34 +440,28 @@ fn current_process_argv0() -> String { } } -fn preflight_proc_mount_support( - sandbox_policy_cwd: &Path, - command_cwd: &Path, - file_system_sandbox_policy: &FileSystemSandboxPolicy, - network_mode: BwrapNetworkMode, -) -> CodexResult { - let preflight_argv = build_preflight_bwrap_argv( - sandbox_policy_cwd, - command_cwd, - file_system_sandbox_policy, - network_mode, - )?; +fn preflight_proc_mount_support(network_mode: BwrapNetworkMode) -> CodexResult { + let preflight_argv = build_preflight_bwrap_argv(network_mode)?; let stderr = run_bwrap_in_child_capture_stderr(preflight_argv); Ok(!is_proc_mount_failure(stderr.as_str())) } fn build_preflight_bwrap_argv( - sandbox_policy_cwd: &Path, - command_cwd: &Path, - file_system_sandbox_policy: &FileSystemSandboxPolicy, network_mode: BwrapNetworkMode, ) -> CodexResult { + let file_system_sandbox_policy = + FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry { + path: FileSystemPath::Special { + value: FileSystemSpecialPath::Minimal, + }, + access: FileSystemAccessMode::Read, + }]); let preflight_command = vec![resolve_true_command()]; build_bwrap_argv( preflight_command, - file_system_sandbox_policy, - sandbox_policy_cwd, - command_cwd, + &file_system_sandbox_policy, + Path::new("/"), + Path::new("/"), BwrapOptions { mount_proc: true, network_mode, diff --git a/codex-rs/linux-sandbox/src/linux_run_main_tests.rs b/codex-rs/linux-sandbox/src/linux_run_main_tests.rs index 4441af7809..4cfde0ce6f 100644 --- a/codex-rs/linux-sandbox/src/linux_run_main_tests.rs +++ b/codex-rs/linux-sandbox/src/linux_run_main_tests.rs @@ -258,20 +258,32 @@ fn root_write_read_only_carveout_requires_direct_runtime_enforcement() { } #[test] -fn managed_proxy_preflight_argv_is_wrapped_for_full_access_policy() { +fn managed_proxy_preflight_argv_unshares_network() { let mode = bwrap_network_mode( NetworkSandboxPolicy::Enabled, /*allow_network_for_proxy*/ true, ); - let argv = build_preflight_bwrap_argv( - Path::new("/"), - Path::new("/"), - &FileSystemSandboxPolicy::unrestricted(), - mode, - ) - .expect("build preflight argv") - .args; + let argv = build_preflight_bwrap_argv(mode) + .expect("build preflight argv") + .args; assert!(argv.iter().any(|arg| arg == "--")); + assert!(argv.iter().any(|arg| arg == "--unshare-net")); +} + +#[test] +fn proc_mount_preflight_does_not_bind_the_full_filesystem() { + let argv = build_preflight_bwrap_argv(BwrapNetworkMode::FullAccess) + .expect("build preflight argv") + .args; + + assert!(argv.windows(2).any(|window| window == ["--tmpfs", "/"])); + assert!(argv.windows(2).any(|window| window == ["--proc", "/proc"])); + assert!( + !argv + .windows(3) + .any(|window| window == ["--ro-bind", "/", "/"]) + ); + assert!(!argv.windows(3).any(|window| window == ["--bind", "/", "/"])); } #[test]