I got curious on why this happens, and this seems to be because of the gatekeeper integration with `mac_file_check_mmap()`.
It seemed like a bit of a moot security feature of it not restricting the mach maximum protection, and it seems Apple knows this too (snippet from `mmap()` in bsd/kern/mman.c):
``` /* * Ensure that file and memory protections are * compatible. Note that we only worry about * writability if mapping is shared; in this case, * current and max prot are dictated by the open file. * XXX use the vnode instead? Problem is: what * credentials do we use for determination? What if * proc does a setuid? */ maxprot = VM_PROT_EXECUTE; /* TODO: Remove this and restrict maxprot? */ ```
That TODO is already 5 years old, so hopefully nothing will happen there in the future as well (and the `ERR` for `mprotect()` there now would help catch this issue immediately as well).