macOS seatbelt policy misses hw.cachelinesize sysctl (only _compat allowed) — mysqld segfaults inside the sandbox

Open 💬 0 comments Opened Jul 6, 2026 by shawnbutton-os

What version of Codex CLI is running?

codex-cli 0.142.5

What subscription do you have?

ChatGPT Business

Which model were you using?

n/a — the bug is in the sandbox policy and reproduces without any model turn

What platform is your computer?

Darwin 25.5.0 arm64 arm (Apple Silicon macOS)

Codex doctor report

not applicable — reproducible with sandbox-exec alone, see below

What happened?

mysqld (MySQL 8.0.36, macOS ARM build) crashes with SIGSEGV whenever it is started inside the Codex seatbelt sandbox:

mysqld got signal 11 ;
4   mysqld   memory::Aligned_atomic<long>::Aligned_atomic() + 100
5   mysqld   Delegate::Delegate(unsigned int) + 96
6   mysqld   delegates_init() + 44
7   mysqld   init_server_components() + 2224
8   mysqld   mysqld_main(int, char**) + 4604

Root cause: the seatbelt base policy allows hw.cachelinesize_compat but not hw.cachelinesize:

https://github.com/openai/codex/blob/main/codex-rs/sandboxing/src/seatbelt_base_policy.sbpl#L29

MySQL sizes its aligned atomics via sysctlbyname("hw.cachelinesize", ...) and does not check the result (sql/memory/aligned_atomic.h, unchanged on MySQL trunk), so the denied read leaves the cache-line size at 0 and the aligned allocation crashes. Since the _compat variant is allowed, the omission of the real name looks like an oversight rather than a policy decision.

Impact: any project with a MySQL-backed build or test suite cannot run it inside the Codex sandbox — the server segfaults on every start. Reproduced identically under codex sandbox -P :workspace and under a custom [permissions] profile.

Minimal repro (no Codex session needed)

# baseline: initializes fine
mysqld --no-defaults --initialize-insecure --datadir=/tmp/mysql-repro

# deny sysctl-read like the codex sandbox does for hw.cachelinesize: SIGSEGV in delegates_init
rm -rf /tmp/mysql-repro
sandbox-exec -p '(version 1)(allow default)(deny sysctl-read)' \
  mysqld --no-defaults --initialize-insecure --datadir=/tmp/mysql-repro

# allowing just this one name fixes it
rm -rf /tmp/mysql-repro
sandbox-exec -p '(version 1)(allow default)(deny sysctl-read)(allow sysctl-read (sysctl-name "hw.cachelinesize"))' \
  mysqld --no-defaults --initialize-insecure --datadir=/tmp/mysql-repro

Also reproduced end-to-end with the real policy:

codex sandbox -P :workspace -C <repo> -- mysqld --no-defaults --initialize-insecure --datadir=<repo>/tmp-data

What did you expect to happen?

mysqld starts inside the sandbox. Suggested fix — add the non-_compat name next to the existing entry in seatbelt_base_policy.sbpl:

(sysctl-name "hw.cachelinesize")

View original on GitHub ↗