Open kees opened 4 years ago
Note that "W^X enforcement" by itself isn't really all that meaningful, unless you're just trying to prevent benign userspace code from creating W^X mappings. For example, something like:
mapping = mmap(NULL, 0x8000, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
remap_file_pages(mapping+0x4000, 0x4000, 0, 0, 0);
mprotect(mapping+0x4000, 0x4000, PROT_READ|PROT_WRITE);
creates two mappings next to each other, where you can write code into one and then execute it through the other.
And it goes further, because you can do the same with files stored to the filesystem (including memfd or /dev/shm/
). So if you want to prevent someone who can already make arbitrary syscalls somehow from mapping arbitrary executable code, you basically have to do SELinux-style enforcement with file labels or something like that, or alternatively something based on mountpoints. And also add a security control for FOLL_FORCE
writes through /proc/self/mem
, which lets you write to non-writable memory. (I sent a patch series for the latter part years ago, but that never landed and at some point I lost interest.)
This would be effectively a port of CONFIG_PAX_MPROTECT, to enforce W^X protection is userspace. Efforts have been made to do this via a couple LSMs: