macOS arm64 release links non-public liblzma/libbz2 → App Store rejection (2.5.1)
Summary
The published codex-aarch64-apple-darwin binary dynamically links the non-public macOS system libraries /usr/lib/liblzma.5.dylib and /usr/lib/libbz2.1.0.dylib, and imports the symbols _lzma_code, _lzma_end, _lzma_stream_decoder, and _BZ2_bzDecompress*. Those dylibs ship on macOS but are not part of the public SDK, so any sandboxed / Mac App Store app that bundles this binary is rejected by App Review under Guideline 2.5.1 – Performance – Software Requirements.
The codex-x86_64-apple-darwin binary is clean — it links neither library and imports none of those symbols.
Real-world impact
This blocked a Mac App Store submission. App Review's response:
The app uses or references the following non-public or deprecated APIs: Contents/Helpers/codex — Symbols:_lzma_code,_lzma_end,_lzma_stream_decoder
Any macOS app that bundles the codex CLI for App Store / sandboxed distribution hits this. Because the x86_64 slice is already clean, the arm64 linkage looks like a build-environment artifact rather than a functional requirement.
Evidence
# arm64 slice of the universal release binary
$ otool -L codex
...
/usr/lib/liblzma.5.dylib (compatibility version 6.0.0, current version 6.3.0)
/usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.8)
...
$ nm -u -arch arm64 codex | grep -iE 'lzma|bz2'
_BZ2_bzDecompress
_BZ2_bzDecompressEnd
_BZ2_bzDecompressInit
_lzma_code
_lzma_end
_lzma_stream_decoder
# x86_64 slice — clean
$ nm -u -arch x86_64 codex | grep -iE 'lzma|bz2'
(no output)
$ otool -L -arch x86_64 codex | grep -iE 'liblzma|libbz2'
(no output)
Reproduced identically on every release from rust-v0.134.0 through rust-v0.139.0 (arm64 dirty, x86_64 clean).
Root cause
The symbols come transitively from lzma-sys / xz2 and bzip2-sys / bzip2 (pulled in via zip). Those -sys crates dynamically link the system liblzma / libbz2 when they're available in the build environment instead of statically compiling their bundled C sources. The macOS arm64 release build environment has them; the x86_64 build apparently doesn't, which is why the two slices diverge.
Proposed fix
Set the documented static-linking environment variables when building the macOS release (the arm64 build in particular) so the bundled C sources are compiled in statically:
LZMA_API_STATIC=1 BZIP2_STATIC=1 cargo build --release ...
This makes the arm64 build match the already-clean x86_64 build, with no source changes and no behavioral difference. (Alternatively, drop the bzip2 / lzma features from the zip dependency if they aren't actually needed.)
I verified locally that rebuilding the arm64 slice from the rust-v0.137.0 tag with LZMA_API_STATIC=1 BZIP2_STATIC=1 produces a functionally identical binary with zero references to liblzma/libbz2 and none of the flagged symbols — lipo'd together with the stock x86_64 release slice it passes App Review's static scan.
Environment
- Affected artifact:
codex-aarch64-apple-darwin(arm64 slice) - Versions checked:
rust-v0.134.0–rust-v0.139.0 - macOS, Apple Silicon
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗