macos entitlements - com.apple.security.cs.allow-unsigned-executable-memory vs com.apple.security.cs.allow-jit

In context of entitlements that are applicable on macos platform, I was discussing in another thread about the com.apple.security.cs.allow-unsigned-executable-memory and the com.apple.security.cs.allow-jit entitlements in a hardened runtime https://developer.apple.com/forums/thread/775520?answerId=827440022#827440022

In that thread it was noted that:

The hardened runtime enables a bunch of additional security checks. None of them are related to networking. Some of them are very important to a Java VM author, most notably the com.apple.security.cs.allow-jit -> com.apple.security.cs.allow-unsigned-executable-memory -> com.apple.security.cs.disable-executable-page-protection cascade. My advice on that front:

This sequence is a trade off between increasing programmer convenience and decreasing security. com.apple.security.cs.allow-jit is the most secure, but requires extra work in your code.

Only set one of these entitlements, because each is a superset of its predecessor.

com.apple.security.cs.disable-executable-page-protection is rarely useful. Indeed, on Apple silicon [1] it’s the same as com.apple.security.cs.allow-unsigned-executable-memory.

If you want to investigate moving from com.apple.security.cs.allow-unsigned-executable-memory to com.apple.security.cs.allow-jit, lemme know because there are a bunch of additional resources on that topic.

What that tells me is that com.apple.security.cs.allow-jit is the recommended entitlement that retains enough security and yet provides the necessary programmer convenience for applications.

In the OpenJDK project we use both com.apple.security.cs.allow-unsigned-executable-memory and com.apple.security.cs.allow-jit entitlements for the executables shipped in the JDK (for example java). I was told in that other thread that it might be possible to just use the com.apple.security.cs.allow-unsigned-executable-memory, but there are some additional details to consider. I'm starting this thread to understand what those details are.

Answered by DTS Engineer in 828593022

The JIT story varies by platform and by CPU architecture. I’m gonna focus on:

  • macOS — While it’s now possible to do JIT on iOS, that’s only in the context of BrowserEngineKit.

  • Apple silicon — The techniques used on Intel continue to work on Intel, including Rosetta, but the Apple silicon techniques work on both architectures. So, if you’re writing new code, you might as well lean into the new stuff.

With that stage set, my go-to reference for this stuff is Porting just-in-time compilers to Apple silicon.

I think that’s all you need, but I’m gonna ask a colleague to double check and then chime in if I missed anything.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The JIT story varies by platform and by CPU architecture. I’m gonna focus on:

  • macOS — While it’s now possible to do JIT on iOS, that’s only in the context of BrowserEngineKit.

  • Apple silicon — The techniques used on Intel continue to work on Intel, including Rosetta, but the Apple silicon techniques work on both architectures. So, if you’re writing new code, you might as well lean into the new stuff.

With that stage set, my go-to reference for this stuff is Porting just-in-time compilers to Apple silicon.

I think that’s all you need, but I’m gonna ask a colleague to double check and then chime in if I missed anything.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

In the OpenJDK project we use both com.apple.security.cs.allow-unsigned-executable-memory and com.apple.security.cs.allow-jit entitlements for the executables shipped in the JDK (for example java).

Let me start by clarifying what exactly those entitlements "do":

com.apple.security.cs.allow-jit-> "A Boolean value that indicates whether the app may create writable and executable memory using the MAP_JIT flag."

MAP_JIT is a specific mmap mode that allows to create PROT_WRITE/PROT_EXEC that can then only be manipulated through a very specific process, the details of what are basically what "Porting just-in-time compilers to Apple silicon" is actually about.

com.apple.security.cs.allow-unsigned-executable-memory-> "A Boolean value that indicates whether the app may create writable and executable memory without the restrictions imposed by using the MAP_JIT flag."

In other words, including both is pointless because "com.apple.security.cs.allow-unsigned-executable-memory" allows MAP_JIT "and more". That relationship is why we recommend you only include one of those entitlements. It's not that including both "does" anything different, it's that including both indicates that you don't understand what the two entitlements actually "do".

What that tells me is that com.apple.security.cs.allow-jit is the recommended entitlement that retains enough security and yet provides the necessary programmer convenience for applications.

Yes, but focusing on the entitlement is misleading. The recommendation here isn't about the entitlement itself, it's specifically about how your code actually works. Building on MAP_JIT means that you're bottlenecking all executable page modification through "pthread_jit_write_with_callback_np", making that memory far harder to exploit. The rest of "Porting just-in-time compilers" then outlines further protections built on that foundation, with the over all goal being to ensure that the ONLY code that's actually capable of modifying those executable pages is the code you intended to "do" that.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you Kevin for these helpful details. I'm still catching up with the linked documents and I'll respond once I have gone through those.

macos entitlements - com.apple.security.cs.allow-unsigned-executable-memory vs com.apple.security.cs.allow-jit
 
 
Q