[PATCH 0/4] macOS/arm64 support

Martin Storsjö martin at martin.st
Fri Aug 21 04:15:39 CDT 2020


On Sat, 15 Aug 2020, Stefan Dösinger wrote:

>
>       - Setting -pagezero_size to anything less than 4 GB seems to
>       make
>        macOS refuse to run the executable. So this makes it impossible
>       to
>        map anything into the lower 4 GB of the address space. For now,
>        I've worked it around by moving the address at which
>       user_shared_data
>        is allocated.
> 
> 
> Shouldn't you be able to forcefully remap parts in the zero page? To my
> knowledge the only thing you can't do is unmap pages that the dynamic loader
> thinks are allocated - if it gets them again when loading a different .dylib
> it will crash and burn. But you can map stuff there with MAP_FIXED yourself
> as long as you can be sure you don't overwrite anything important - which
> shouldn't be the case in the zero page.

I tried this out with this small test snippet on Catalina:

#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
     void *target = (void*)0x7ffe0000;
     char *ptr = mmap(target, 4*4096,
                      PROT_READ | PROT_WRITE,
                      MAP_ANON | MAP_PRIVATE | MAP_FIXED, 0, 0);
     if (ptr == MAP_FAILED) {
         perror("mmap");
         return 1;
     }
     printf("mmap fixed at %p returned %p\n", target, ptr);
     return 0;
}

If linked without pagezero_size, I get "mmap: Cannot allocate memory", 
while it succeeds if linked with that option.


>       - Memory mappings can't be writable and executable at the same
>       time.
>        If one mmap()s a page and request it to be both writable and
>        executable, writing to it fails, same if changing protection
>       with
>        mprotect().
> 
> 
> In Catalina you can bypass that with the right protected runtime
> entitlements. That means you'll have to sign your executable with a manifest
> that enables the protected runtime and requests the entitlements. Do you
> know if this still works in Big Sur x86_64 and/or big sur ARM?

When trying this out on Catalina on x86_64, such mappings work just fine 
normally. If I enabled the hardened runtime by signing it with "codesign 
-o runtime", the mmap calls that request writable+executable memory fail 
with EPERM. If I add entitlements to the signing, either 
com.apple.security.cs.allow-unsigned-executable-memory or 
com.apple.security.cs.disable-executable-page-protection it succeeds 
again.

On Big Sur on arm64, the mmap calls don't fail but do return a pointer to 
some memory, but the supposedly writable+executable memory fails if 
written to. The same happens there, if I opt in to the hardened runtime, 
the mmap call fails, but if I add those entitlements, I get back to the 
original behaviour - mmap succeeds, but the memory actually isn't 
writable.

// Martin


More information about the wine-devel mailing list