[pcre-dev] [Bug 2618] JIT crash in macOS 11 with ARM64 hardw…

Top Page
Delete this message
Author: admin
Date:  
To: pcre-dev
Old-Topics: [pcre-dev] [Bug 2618] New: Patch with JIT support for macOS ARM64 hardware
Subject: [pcre-dev] [Bug 2618] JIT crash in macOS 11 with ARM64 hardware
https://bugs.exim.org/show_bug.cgi?id=2618

Carlo Marcelo Arenas Belón <carenas@???> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|Other                       |All


--- Comment #15 from Carlo Marcelo Arenas Belón <carenas@???> ---
(In reply to Saagar Jha from comment #13)
> the mmap call must be done with the MAP_JIT flag, and you must
> sign your code with the com.apple.security.cs.allow-jit entitlement. If you
> fail to do this (AFAIK) your process will be killed for a codesigning
> violation once you try to execute the code you've generated.


FWIW we had been setting MAP_JIT for macOS for several releases and we had not
seen a report of a process killed for codesigning violation until the recent
crash logs (sadly they have no debug information, but would seem to be the
case)

iOS, tvOS, ipadOS and all other sibling architectures should be triggering the
same, but would be important to test that to make sure the issue is because of
the recent change in the API to ALSO require pthread_jit_write_protect_np() and
not the way the apple arm processors with APRR (which seems to be at least
available for maybe the last 3 generations) behave with MAP_JIT (which has also
been available for several releases, even if not really documented).

> Memory allocated RWX will effectively be made R-X


note the crash points to a page with RWX permissions though but that might be
a sideeffect of how the ARM mask permission is applied on top of what the OS
reports.

> Apple's
> intended solution is that you use the pthread_jit_write_protect_np(0) call
> in before writing code to this region (changing effective permissions to
> RW-) and then using the call again (pthread_jit_write_protect_np(1)) to set
> permissions back to R-X so you can execute it


probably a rhetorical question, but any idea why it seems to be backwards? it
makes more sense to have the permission initially be RW so you can write the
code before moving to RX so it can be executed.

indeed, I just implemented something similar for NetBSD W^X and the patch to
PCRE (including a whole new "allocator") seems simpler than what macOS might
need.

> * Allocating a RWX region with no special flags and attempting to write code
> to it and execute it. This will fail because you will not have write
> permission due to APRR on ARM chips. Will not work on Intel chips running
> under hardened runtime when the code is attempted to be executed due to
> codesigning, but will work otherwise.


mmap a region RW and then mprotecting it to RX after filling it would work?
it would seem that mmap succeeded though so is a fault the only way to know?

AFAIK there are entitlements to cover that transition which I'll presume should
allow at least Intel to work if codesigning, would the same apply to ARM?

> What will work on ARM, if the memory is correctly allocated based on the
> runtime hardening setting:
>
> * Using one thread: interleaving calls to pthread_jit_write_protect_np when
> switching between writing to the JIT region and executing it.


this is what fits better our model, any insights on what would happen though
if the application is single threaded?, is linking with pthread the way to
have pthread_jit_write_protect_np available and therefore single threaded
applications can't do JIT except for the option below?

> * Using one thread: modifying a proprietary register before you try to write
> code into this region, which will disable this APRR feature altogether for
> the program:
>
> unsigned long long mask;
> __asm__ volatile("mrs %0, s3_4_c15_c2_7" : "=r"(mask): :);
> __asm__ volatile("msr s3_4_c15_c2_7, %0" : : "r"(mask & 0xfffffffff0ffffff)
> :);
>
> This has the upside that you only have to do it once early at program
> startup and never have to deal with it again, but the downside is that I
> don't think Apple would particularly approve of this.


is there a source for this available online?, is there an "equivalent" snippet
for Intel or another way to do single threaded JIT?

am I wrong in consider pthread_jit_write_protect_np() calls something that
needs to be done regardless of CPU type as it seems to be mandated by the API
(included in macOS 11, and some yet undetermined versions for iOS and friends)


> And by the way, here
> is a "real" application crashing due to this change


for pcre (legacy or 8.x) the best option is (as was done already in brew) to
disable jit at build time, but failing to detect a broken allocator in
pcre_study() is another bug that I am worried might be probably a side effect
of the way the mmap/mprotect calls are failing to report failures and that
should be raised with Apple

--
You are receiving this mail because:
You are on the CC list for the bug.