Closed Bug 1474447 Opened 6 years ago Closed 3 months ago

[macOS 10.14] Use MAP_JIT for all executable JIT pages for 10.14 Enhanced Runtime

Categories

(Core :: JavaScript Engine: JIT, enhancement, P3)

63 Branch
Unspecified
macOS
enhancement

Tracking

()

RESOLVED FIXED
123 Branch
Tracking Status
firefox63 --- wontfix
firefox123 --- fixed

People

(Reporter: haik, Assigned: jandem)

References

(Blocks 2 open bugs)

Details

(Keywords: sec-want, Whiteboard: [adv-main123-])

Attachments

(1 file)

macOS 10.14 will allow apps to opt-in to an "Enhanced Runtime" allowing the OS to enforce that all executable code pages match their on-disk signature. This includes an exception apps can use that allows pages mapped with the MAP_JIT flag to be executed. Without the MAP_JIT support in the JS engine, we would still be able opt-in to the Enhanced Runtime, but we'd have to disable all code signing protection using the com.apple.security.cs.disable-executable-page-protection option.

We have bug 1470597 filed to cover enabling Enhanced Runtime which requires building with the 10.14 SDK.

So far, the only details available are in this WWDC video.
  https://developer.apple.com/videos/play/wwdc2018/702/
Depends on: 1470597
Summary: [Mac] Use MAP_JIT for all executable JIT pages for 10.14 Enhanced Runtime → [macOS 10.14] Use MAP_JIT for all executable JIT pages for 10.14 Enhanced Runtime
Blocks: mojave
What is the deadline for 10.14 release? When would this become mandatory?
Is MAP_JIT this backward compatible with old versions of Mac?
Flags: needinfo?(haftandilian)
Priority: -- → P3
The talk mention that this would be backward compatible, but I am not sure how.
Also, it mentions (starting at ~21:40 in the video) that the allow-jit and MAP_JIT corresponds to RWX, which sounds worst than the W^X.
(In reply to Nicolas B. Pierron [:nbp] {backlog: 39} from comment #1)
> What is the deadline for 10.14 release?

We don't have a specific deadline for this work. Before we can adopt Enhanced Runtime (and then consider using MAP_JIT), we have to build Firefox with the 10.14 SDK and we haven't prioritized that work yet.

> When would this become mandatory?

We don't know of a date when this will become mandatory. Apple mentioned in the talk that the Notarized App feature might become mandatory in the future, but using this MAP_JIT flag isn't a requirement for for that. We could opt into Enhanced Runtime and disable the executable page protection.

> Is MAP_JIT this backward compatible with old versions of Mac?

We may have to do an OS version check at runtime before using it. The MAP_JIT mmap flag is in older OS X kernels, but behavior might be undefined for our use. We have to support OS versions 10.9+ for now.
Flags: needinfo?(haftandilian)
(In reply to Nicolas B. Pierron [:nbp] {backlog: 39} from comment #2)
> The talk mention that this would be backward compatible, but I am not sure
> how. Also, it mentions (starting at ~21:40 in the video) that the allow-jit and
> MAP_JIT corresponds to RWX, which sounds worst than the W^X.

MAP_JIT isn't mentioned in the 10.14 Beta man pages so I don't know how to confirm that for now. But we should carefully evaluate if using MAP_JIT is an actual improvement before doing this work.
Depends on: mojave-sdk

(In reply to Haik Aftandilian [:haik] from comment #3)

(In reply to Nicolas B. Pierron [:nbp] {backlog: 39} from comment #1)

What is the deadline for 10.14 release?

We don't have a specific deadline for this work. Before we can adopt
Enhanced Runtime (and then consider using MAP_JIT), we have to build Firefox
with the 10.14 SDK and we haven't prioritized that work yet.

That was incorrect. Building with the 10.14 SDK is not required to enable Hardened Runtime (aka Enhanced Runtime.) It does require running the codesign command on 10.13.6 or newer, but that's a build/releng issue.

No longer depends on: mojave-sdk

I looked into this a bit today. I think we could make this work with a number of changes to the JIT code allocator, but when I tried to switch from com.apple.security.cs.allow-unsigned-executable-memory = true to com.apple.security.cs.allow-jit = true I ran into issues with the IOInterposer patching binary code, so turning off allow-unsigned-executable-memory will require more work...

Severity: normal → S3
Depends on: 1837194

Bug 1837194 is doing this for Apple Silicon hardware for performance reasons. We could probably also fix this for Intel machines now. It depends a bit on which operations the kernel allows there for MAP_JIT pages.

The Apple Silicon MAP_JIT changes have stuck and I think it's worth trying to do the same for Intel Macs now. It also helps that we no longer support macOS <= 10.14 since Firefox 115 because older versions didn't support MAP_JIT (or it didn't work the same way).

This will potentially let us remove the allow-unsigned-executable-memory entitlement. The IOInterposer probably also requires it, but that isn't enabled on release AFAICT so if there's no other blocker we could at least improve the situation for the release channel.

Flags: needinfo?(jdemooij)

We've been using MAP_JIT on Apple Silicon since bug 1837194.

With this change we no longer need the com.apple.security.cs.allow-unsigned-executable-memory
entitlement for the JITs (pre-release Firefox still needs it for the IOInterposer
on Intel).

Support for MAP_JIT is enabled by the separate com.apple.security.cs.allow-jit entitlement.

Intel Macs don't have the pthread_jit_write_protect_np API, so we use a similar
strategy as on Apple Silicon but with mprotect added to it.

Assignee: nobody → jdemooij
Status: NEW → ASSIGNED

With this patch + setting MOZ_DISABLE_POISON_IO_INTERPOSER=1 I can start a codesigned Firefox build without the allow-unsigned-executable-memory entitlement on my Intel MBP \o/

Flags: needinfo?(jdemooij)
Keywords: sec-want
Blocks: 1474451

(In reply to Jan de Mooij [:jandem] from comment #10)

With this patch + setting MOZ_DISABLE_POISON_IO_INTERPOSER=1 I can start a codesigned Firefox build without the allow-unsigned-executable-memory entitlement on my Intel MBP \o/

Awesome! Could the Interposer be changed to use MAP_JIT too?

(In reply to Haik Aftandilian [:haik] from comment #11)

Awesome! Could the Interposer be changed to use MAP_JIT too?

I'm not very familiar with it, but I think it works by patching code. MAP_JIT doesn't really work for that use case because the code is already allocated and mapped, we just need to make it writable.

Pushed by jdemooij@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/50441fc22b6d
Use MAP_JIT on Intel Macs too. r=iain
Status: ASSIGNED → RESOLVED
Closed: 3 months ago
Resolution: --- → FIXED
Target Milestone: --- → 123 Branch
Whiteboard: [adv-main123-]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: