[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