From 46b8d127cf372378945b53f79c82cd0341fe870e Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Sat, 7 Mar 2026 20:29:35 -0800 Subject: [PATCH] sandboxing: preserve denied paths when widening permissions (#13451) ## Why After the split-policy plumbing landed, additional-permissions widening still rebuilt filesystem access through the legacy projection in a few places. That can erase explicit deny entries and make the runtime treat a policy as fully writable even when it still has blocked subpaths, which in turn can skip the platform sandbox when it is still needed. ## What changed - preserved explicit deny entries when merging additional read and write permissions into `FileSystemSandboxPolicy` - switched platform-sandbox selection to rely on `FileSystemSandboxPolicy::has_full_disk_write_access()` instead of ad hoc root-write checks - kept the widened policy path in `core/src/exec.rs` and `core/src/sandboxing/mod.rs` aligned so denied subpaths survive both policy merging and sandbox selection - added regression coverage for root-write policies that still carry carveouts ## Verification - added regression coverage in `core/src/sandboxing/mod.rs` showing that root write plus carveouts still requires the platform sandbox - verified the current PR state with `just clippy` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/13451). * #13453 * #13452 * __->__ #13451 * #13449 * #13448 * #13445 * #13440 * #13439 --------- Co-authored-by: viyatb-oai --- codex-rs/core/src/sandboxing/mod.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/codex-rs/core/src/sandboxing/mod.rs b/codex-rs/core/src/sandboxing/mod.rs index 69ab438e1..ecbdbed93 100644 --- a/codex-rs/core/src/sandboxing/mod.rs +++ b/codex-rs/core/src/sandboxing/mod.rs @@ -35,7 +35,6 @@ use codex_protocol::permissions::FileSystemPath; use codex_protocol::permissions::FileSystemSandboxEntry; use codex_protocol::permissions::FileSystemSandboxKind; use codex_protocol::permissions::FileSystemSandboxPolicy; -use codex_protocol::permissions::FileSystemSpecialPath; use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::protocol::NetworkAccess; use codex_protocol::protocol::ReadOnlyAccess; @@ -215,7 +214,6 @@ fn additional_permission_roots( ) } -#[cfg_attr(not(test), allow(dead_code))] fn merge_file_system_policy_with_additional_permissions( file_system_policy: &FileSystemSandboxPolicy, extra_reads: Vec, @@ -369,14 +367,7 @@ pub(crate) fn should_require_platform_sandbox( } match file_system_policy.kind { - FileSystemSandboxKind::Restricted => !file_system_policy.entries.iter().any(|entry| { - entry.access == FileSystemAccessMode::Write - && matches!( - &entry.path, - FileSystemPath::Special { value } - if matches!(value, FileSystemSpecialPath::Root) - ) - }), + FileSystemSandboxKind::Restricted => !file_system_policy.has_full_disk_write_access(), FileSystemSandboxKind::Unrestricted | FileSystemSandboxKind::ExternalSandbox => false, } }