shared/seccomp: disallow pkey_mprotect the same as mprotect for W^X mappings (#7295)

MemoryDenyWriteExecution policy could be be bypassed by using pkey_mprotect
instead of mprotect to create an executable writable mapping.

The impact is mitigated by the fact that the man page says "Note that this
feature is fully available on x86-64, and partially on x86", so hopefully
people do not rely on it as a sole security measure.

Found by Karin Hossen and Thomas Imbert from Sogeti ESEC R&D.

https://bugs.launchpad.net/bugs/1725348
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2017-11-12 17:28:48 +01:00 committed by GitHub
parent ce5faeac1f
commit b835eeb4ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 2 deletions

View File

@ -1869,8 +1869,9 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
memory segments as executable are prohibited. Specifically, a system call filter is added that rejects
<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with both
<constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
<citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
<constant>PROT_EXEC</constant> set and
<citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry>
or <citerefentry><refentrytitle>pkey_mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry>
system calls with <constant>PROT_EXEC</constant> set and
<citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
<constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs and libraries that
generate program code dynamically at runtime, including JIT execution engines, executable stacks, and code

View File

@ -1440,6 +1440,12 @@ int seccomp_memory_deny_write_execute(void) {
if (r < 0)
continue;
r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(pkey_mprotect),
1,
SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
if (r < 0)
continue;
if (shmat_syscall != 0) {
r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(shmat),
1,