Bypass seccomp-bpf based memory-deny-write-execute with `READ_IMPLIES_EXEC` =========================================================================== The most seccomp-bpf based memory-deny-write-execute implementations can be bypassed. Well known ways to bypass them are 1. mapping a file from a filesystem that is not mounted `noexec` (e.g. `/dev/shm`). 2. `memfd_create` - systemd recommends to deny `memfd_create` with `SystemCallFilter=~memfd_create`. - firejail's `memory-deny-write-execute` implementation denies `memfd_create`. This is more secure but makes `memory-deny-write-execute` unusable for programs that need (non-exec) `memfd_create` like the most GNOME programs. - syd emulates `memfd_create` by using `MFD_NOEXEC_SEAL` by default. - crablock allows to deny executable `memfd`s with `--seccomp-memfd-noexec` or deny `memfd_create` entirely with `--seccomp-syscall-filter`. 3. `shmat` on architectures that multiplex it through `ipc`. - firejail can block secondary architectures with `seccomp.block-secondary`. - systemd recommends to set `SystemCallArchitectures=native`. - crablock does not allow secondary architectures in its seccomp filters. - If the primary architecture multiplexes it, nothing can be done. However there is a fourth bypass that is neither mentioned in the documentation of firejail or systemd nor blocked by their seccomp-bpf based mdwe implementations. The **`READ_IMPLIES_EXEC`** `personality` flag that can be used to create a mapping that is executable without requesting `PROT_EXEC` in the `mmap` call. ``` PROT_WRITE | PROT_EXEC: FAILED PROT_READ | PROT_WRITE: SUCCESS: 7f48d8515000-7f48d8516000 rw-p 00000000 00:00 0 Set personality READ_IMPLIES_EXEC. PROT_WRITE | PROT_EXEC: FAILED PROT_READ | PROT_WRITE: SUCCESS: 7f48d8514000-7f48d8515000 rwxp 00000000 00:00 0 Mapping is W&X! 🧨 ``` - systemd's `MemoryDenyWriteExecute=yes` uses `PR_MDWE_REFUSE_EXEC_GAIN` if available which can not be bypassed that way. Otherwise you can (and should always) use `LockPersonality=yes`. - firejail denyies `personality` with `seccomp` unless `allow-debuggers` is used. - crablock's `--seccomp-memory-deny-write-execute` denies calls to `personality` that try to set `READ_IMPLIES_EXEC`. crablock also implements `--mdwe-refuse-exec-gain` which can not be bypassed that way. --- Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.