From 696b4502dfaacd91133c3691a23dc91ae3b14bc9 Mon Sep 17 00:00:00 2001 From: viyatb-oai Date: Fri, 21 Aug 2026 17:01:30 +0000 Subject: [PATCH] Allow semaphore limit queries in the macOS sandbox (#39976) ## Why Python's `ProcessPoolExecutor` queries `SEM_NSEMS_MAX` through `sysconf`, which reads the `kern.sysv.semmns` sysctl on macOS. ## What changed - Allow reads of `kern.sysv.semmns` in the base Seatbelt policy. - Verify `/usr/bin/getconf SEM_NSEMS_MAX` succeeds with both read-only and workspace-write sandbox policies. GitOrigin-RevId: ab3ae92dc8991729f90a47c1994eedb6c7a2b9cd --- .../sandboxing/src/seatbelt_base_policy.sbpl | 2 ++ codex-rs/sandboxing/src/seatbelt_tests.rs | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/codex-rs/sandboxing/src/seatbelt_base_policy.sbpl b/codex-rs/sandboxing/src/seatbelt_base_policy.sbpl index ba3140aa44..2fca6a886e 100644 --- a/codex-rs/sandboxing/src/seatbelt_base_policy.sbpl +++ b/codex-rs/sandboxing/src/seatbelt_base_policy.sbpl @@ -64,6 +64,8 @@ (sysctl-name "kern.osvariant_status") (sysctl-name "kern.osversion") (sysctl-name "kern.secure_kernel") + ; Python's ProcessPoolExecutor queries this through sysconf(_SC_SEM_NSEMS_MAX). + (sysctl-name "kern.sysv.semmns") (sysctl-name "kern.usrstack64") (sysctl-name "kern.version") (sysctl-name "sysctl.proc_cputype") diff --git a/codex-rs/sandboxing/src/seatbelt_tests.rs b/codex-rs/sandboxing/src/seatbelt_tests.rs index e9e42f054a..ce8fae2a56 100644 --- a/codex-rs/sandboxing/src/seatbelt_tests.rs +++ b/codex-rs/sandboxing/src/seatbelt_tests.rs @@ -136,6 +136,41 @@ fn base_policy_allows_node_cpu_sysctls() { ); } +#[test] +fn seatbelt_allows_semaphore_limit_sysconf() { + let workspace = TempDir::new().expect("temp workspace"); + for policy in [ + SandboxPolicy::new_read_only_policy(), + SandboxPolicy::new_workspace_write_policy(), + ] { + // getconf calls the same sysconf used by Python's ProcessPoolExecutor. + let args = create_seatbelt_command_args_for_legacy_policy( + vec!["/usr/bin/getconf".to_string(), "SEM_NSEMS_MAX".to_string()], + &policy, + workspace.path(), + /*enforce_managed_network*/ false, + /*network*/ None, + ) + .expect("create seatbelt args"); + let output = Command::new(MACOS_PATH_TO_SEATBELT_EXECUTABLE) + .args(args) + .current_dir(workspace.path()) + .output() + .expect("execute semaphore limit query under seatbelt"); + let stderr = String::from_utf8_lossy(&output.stderr); + if !output.status.success() + && stderr.contains("sandbox-exec: sandbox_apply: Operation not permitted") + { + eprintln!("skipping semaphore limit query: nested Seatbelt is unavailable"); + return; + } + assert!( + output.status.success(), + "semaphore limit query should succeed under {policy:?}: {stderr}" + ); + } +} + #[test] fn base_policy_allows_kmp_registration_shm_read_create_and_unlink() { let expected = r##"(allow ipc-posix-shm-read-data