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
This commit is contained in:
viyatb-oai
2026-08-21 17:01:30 +00:00
committed by copyberry
parent d12a7f3fd8
commit 696b4502df
2 changed files with 37 additions and 0 deletions

View File

@@ -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")

View File

@@ -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