seccomp: allow shmat to be a separate syscall on architectures which use a multiplexer
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 15 Mar 2019 11:46:56 +0000 (12:46 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 15 Mar 2019 14:46:41 +0000 (15:46 +0100)
After
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0d6040d46817,
those syscalls have their separate numbers and we can block them.
But glibc might still use the old ones. So let's just do a best-effort
block and not assume anything about how effective it is.

src/shared/seccomp-util.c
src/test/test-seccomp.c

index 714734a..905be0f 100644 (file)
@@ -1519,6 +1519,7 @@ int seccomp_memory_deny_write_execute(void) {
                 case SCMP_ARCH_X86:
                         filter_syscall = SCMP_SYS(mmap2);
                         block_syscall = SCMP_SYS(mmap);
+                        shmat_syscall = SCMP_SYS(shmat);
                         break;
 
                 case SCMP_ARCH_PPC:
@@ -1585,7 +1586,7 @@ int seccomp_memory_deny_write_execute(void) {
                         continue;
 #endif
 
-                if (shmat_syscall != 0) {
+                if (shmat_syscall > 0) {
                         r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(shmat),
                                                        1,
                                                        SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
index 937d414..14b37ee 100644 (file)
@@ -548,15 +548,18 @@ static void test_memory_deny_write_execute_shmat(void) {
                 assert_se(seccomp_memory_deny_write_execute() >= 0);
 
                 p = shmat(shmid, NULL, SHM_EXEC);
+                log_debug_errno(p == MAP_FAILED ? errno : 0, "shmat(SHM_EXEC): %m");
 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
                 assert_se(p == MAP_FAILED);
                 assert_se(errno == EPERM);
-#else /* __i386__, __powerpc64__, and "unknown" architectures */
-                assert_se(p != MAP_FAILED);
-                assert_se(shmdt(p) == 0);
 #endif
+                /* Depending on kernel, libseccomp, and glibc versions, other architectures
+                 * might fail or not. Let's not assert success. */
+                if (p != MAP_FAILED)
+                        assert_se(shmdt(p) == 0);
 
                 p = shmat(shmid, NULL, 0);
+                log_debug_errno(p == MAP_FAILED ? errno : 0, "shmat(0): %m");
                 assert_se(p != MAP_FAILED);
                 assert_se(shmdt(p) == 0);