There are two things that you are observing:
mprotect
was not designed to be used with heap pages. Linux and OS X have slightly different handling of the heap (remember that OS X uses the Mach VM). OS X does not like it's heap pages to be tampered with.You can get identical behaviour on both OSes if you allocate your page via
mmap
a = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (a == MAP_FAILED) perror("mmap");
This is a restriction of your MMU (x86 in my case). The MMU in x86 does not support writable, but not readable pages. Thus setting
mprotect(a, pagesize, PROT_WRITE)
does nothing. while
mprotect(a, pagesize, PROT_READ)
removed write priveledges and you get a SIGSEGV as expected.
Also although it doesn't seem to be an issue here, you should either compile your code with -O0
or set a
to volatile int *
to avoid any compiler optimisations.