-1

I am trying to run the code example in this answer https://stackoverflow.com/a/38974980 on macOS 13, and the program gives segmentation fault.

In fact, let's simplify the program linked above to

#include<sys/mman.h>
#include<stddef.h>
int main(){
    size_t size = 100;
    char* buf = (char*) mmap(NULL, (size_t) size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    *buf = 'a';
    return 0;
}

And even this simple program gives segmentation fault on macOS. The mmap does not return null pointer, but the pointer cannot be accessed. Removing PROT_EXEC fixes the problem, but the whole point is to allocate executable memory. Why is it not working? How could I fix it?

Mr User
  • 205
  • 1
  • 5

1 Answers1

0

Looks like you need at least MAP_JIT, but even that won’t save you on Apple Silicon:

This Apple document states:

When memory protection is enabled, a thread cannot write to a memory region and execute instructions in that region at the same time. Apple silicon enables memory protection for all apps, regardless of whether they adopt the Hardened Runtime. Intel-based Mac computers enable memory protection only for apps that adopt the Hardened Runtime.

It goes on to explain what you need to do. It’s a bit long to quote, but it boils down to using pthread_jit_write_protect_np to disable memory protection before writing, and to enable it again before executing.

Ture Pålsson
  • 6,088
  • 2
  • 12
  • 15