macOS 14.2: sandbox startup fails with unbound variable TIOCSTI
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Environment
- macOS 14.2 (23C64), Apple Silicon.
- Codex desktop 26.908.40834, bundle build 8881.
- Bundled CLI:
codex-cli 0.154.0-alpha.6.2. - Also inspected current upstream
mainat70eb36203dbb8c75d006b39cdfae74bd04e18a65; it contains the same symbolic rule. - No model request, account access, or project is needed to reproduce.
Reproduction
Run the desktop app's bundled executable from a terminal:
/Applications/Codex.app/Contents/Resources/codex sandbox -P :read-only -- /usr/bin/true
Actual result: exit 65, before /usr/bin/true starts:
sandbox-exec: unbound variable: TIOCSTI at <input string>, line 132, column 33
Backtrace:
<input string>:132:33:
TIOCSTI
Expected result: /usr/bin/true starts inside the sandbox and exits 0.
Both this installed build and current upstream use the following sandbox syntax (macos is not a subcommand in either):
codex sandbox -P :read-only -- /usr/bin/true
In the desktop app, browser-controller startup fails with the same error before its Node kernel starts. This prevents browser tasks from running; resetting the browser controller reproduces it.
Root cause
The guard added by #42590 in codex-rs/cli/src/debug_sandbox.rs appends:
(deny file-ioctl (ioctl-command TIOCSTI))
On this macOS version, the Seatbelt policy compiler does not define the bare TIOCSTI symbol. The ioctl itself exists: the platform constant is 0x80017472 (2147578994). A minimal policy using the symbolic name reproduces the compilation error; replacing it with the numeric value compiles.
The proposed correction formats the existing platform libc::TIOCSTI constant into that rule. It preserves the denial, rule order, and sandbox permissions; it does not disable terminal-injection protection.
Validation and reference patch
Tested the reference correction on this same macOS 14.2 host, using Rust 1.95.0:
just fmtandgit diff --check: passed.just test -p codex-cli --test sandbox_tty: 2 passed, 0 skipped.just test -p codex-cli --success-output immediate: 451 passed, 0 skipped.target/debug/codex sandbox -P :read-only -- /usr/bin/true: exit 0.
The two Seatbelt tests execute the startup regression and a disposable-PTY control/denial probe. The latter confirms that TIOCSTI succeeds on the unsandboxed control PTY but is denied with EPERM inside the sandbox, with no injected input left queued. Tests ran outside a parent Seatbelt sandbox; the availability check did not skip them.
Reference patch and regression tests: https://github.com/bibryam/codex/pull/1
This issue follows the repository's contribution policy: the code is provided in the reporter's fork as a reference, not as an external upstream PR. No installed app binaries or security settings were modified.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codex-rs/cli/src/debug_sandbox.rs, where the sandbox policy adds the TIOCSTI denial, and run the reproduction command from the issue on macOS. Run the codex-cli sandbox_tty tests and the broader codex-cli test suite; done means the read-only sandbox starts successfully and TIOCSTI remains denied inside it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, rust
- Domain
- cli, operating-systems, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100