We're developing a Mac App Store application that embeds the V8 JavaScript engine (via Electron). The application has shipped successfully on macOS 15.x with the following entitlements:
com.apple.security.app-sandbox= truecom.apple.security.cs.allow-jit= truecom.apple.security.cs.allow-unsigned-executable-memory= truecom.apple.security.cs.disable-library-validation= true
On macOS 26 Tahoe, the exact same signed binary crashes deterministically within ~1.5 seconds on Apple Silicon with EXC_BREAKPOINT (SIGTRAP), ESR 0xf2000000. The crash is in V8's background JIT compilation thread when it attempts to manage memory page protections (transitioning pages between Read-Write and Read-Execute states via mprotect).
The crash does not occur in these configurations:
- macOS 26 + App Sandbox + Intel x86_64 — works
- macOS 26 + Hardened Runtime (no sandbox) + ARM64 — works
- macOS 15.x + App Sandbox + ARM64 — works
This appears to be a regression in how the XNU kernel handles mprotect calls for sandboxed processes on ARM64 under macOS 26, specifically in the context of the allow-jit entitlement.
Has the behavior of allow-jit changed in macOS 26 with respect to runtime code generation memory management on ARM64? Is there a new API or entitlement that V8-style JIT engines should use instead of mprotect-based RW↔RX page transitions?
AFAIK the official guidance hasn’t changed; see Porting just-in-time compilers to Apple silicon.
As to what’s going on with your specific third-party runtime, I don’t have expertise in that codebase so it’s not something I have an opinion about. You have the usual options:
- Seek advice from the runtime vendor.
- Or, as this is open source, dig into the code yourself.
ps It’s very unlikely that library validation is a factor here. Unless you have specific reasons for disabling it, I recommend that you re-enable it. That’s good for security and it helps you avoid various runtime problems caused by build-time issues [1].
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] The one I see all the time is described in Resolving Gatekeeper Problems Caused by Dangling Load Command Paths, but there are others. For example, I sometimes see folks create an app that’s only partially signed, typically because they’ve embedded native code within a zip archive. With library validation disabled, they only find out about that at submission time. With library validation enabled, the code fails to load during development, which is a much easier issue to track down.