From ac58749bd32c9062a74e75ec2ce639e2d2a6779a Mon Sep 17 00:00:00 2001 From: Jeremy Rose <172423086+nornagon-openai@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:28:52 -0700 Subject: [PATCH] allow mach-lookup for com.apple.system.opendirectoryd.libinfo (#3334) in the base sandbox policy. this is [allowed in Chrome renderers](https://source.chromium.org/chromium/chromium/src/+/main:sandbox/policy/mac/common.sb;l=266;drc=7afa0043cfcddb3ef9dafe5acbfc01c2f7e7df01), so I feel it's fairly safe. --- codex-rs/core/src/seatbelt_base_policy.sbpl | 5 +++ codex-rs/core/tests/suite/seatbelt.rs | 35 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/codex-rs/core/src/seatbelt_base_policy.sbpl b/codex-rs/core/src/seatbelt_base_policy.sbpl index b2504948..f165f067 100644 --- a/codex-rs/core/src/seatbelt_base_policy.sbpl +++ b/codex-rs/core/src/seatbelt_base_policy.sbpl @@ -69,3 +69,8 @@ ; Added on top of Chrome profile ; Needed for python multiprocessing on MacOS for the SemLock (allow ipc-posix-sem) + +; needed to look up user info, see https://crbug.com/792228 +(allow mach-lookup + (global-name "com.apple.system.opendirectoryd.libinfo") +) diff --git a/codex-rs/core/tests/suite/seatbelt.rs b/codex-rs/core/tests/suite/seatbelt.rs index 638ac48b..69f1d890 100644 --- a/codex-rs/core/tests/suite/seatbelt.rs +++ b/codex-rs/core/tests/suite/seatbelt.rs @@ -159,6 +159,41 @@ async fn read_only_forbids_all_writes() { .await; } +/// Verify that user lookups via `pwd.getpwuid(os.getuid())` work under the +/// seatbelt sandbox. Prior to allowing the necessary mach‑lookup for +/// OpenDirectory libinfo, this would fail with `KeyError: getpwuid(): uid not found`. +#[tokio::test] +async fn python_getpwuid_works_under_seatbelt() { + if std::env::var(CODEX_SANDBOX_ENV_VAR) == Ok("seatbelt".to_string()) { + eprintln!("{CODEX_SANDBOX_ENV_VAR} is set to 'seatbelt', skipping test."); + return; + } + + // ReadOnly is sufficient here since we are only exercising user lookup. + let policy = SandboxPolicy::ReadOnly; + + let mut child = spawn_command_under_seatbelt( + vec![ + "python3".to_string(), + "-c".to_string(), + // Print the passwd struct; success implies lookup worked. + "import pwd, os; print(pwd.getpwuid(os.getuid()))".to_string(), + ], + &policy, + std::env::current_dir().expect("should be able to get current dir"), + StdioPolicy::RedirectForShellTool, + HashMap::new(), + ) + .await + .expect("should be able to spawn python under seatbelt"); + + let status = child + .wait() + .await + .expect("should be able to wait for child process"); + assert!(status.success(), "python exited with {status:?}"); +} + #[expect(clippy::expect_used)] fn create_test_scenario(tmp: &TempDir) -> TestScenario { let repo_parent = tmp.path().to_path_buf();