macOS arm64 release links non-public liblzma/libbz2 → App Store rejection (2.5.1)

Open 💬 2 comments Opened Jun 15, 2026 by dppeak

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.0rust-v0.139.0
  • macOS, Apple Silicon

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗