Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'seccomp-v5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull seccomp fixes from Kees Cook:
"This fixes a corner case of fatal SIGSYS being ignored since v5.15.
Along with the signal fix is a change to seccomp so that seeing
another syscall after a fatal filter result will cause seccomp to kill
the process harder.

Summary:

- Force HANDLER_EXIT even for SIGNAL_UNKILLABLE

- Make seccomp self-destruct after fatal filter results

- Update seccomp samples for easier behavioral demonstration"

* tag 'seccomp-v5.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
samples/seccomp: Adjust sample to also provide kill option
seccomp: Invalidate seccomp mode to catch death failures
signal: HANDLER_EXIT should clear SIGNAL_UNKILLABLE

+20 -4
+10
kernel/seccomp.c
··· 29 29 #include <linux/syscalls.h> 30 30 #include <linux/sysctl.h> 31 31 32 + /* Not exposed in headers: strictly internal use only. */ 33 + #define SECCOMP_MODE_DEAD (SECCOMP_MODE_FILTER + 1) 34 + 32 35 #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER 33 36 #include <asm/syscall.h> 34 37 #endif ··· 1013 1010 #ifdef SECCOMP_DEBUG 1014 1011 dump_stack(); 1015 1012 #endif 1013 + current->seccomp.mode = SECCOMP_MODE_DEAD; 1016 1014 seccomp_log(this_syscall, SIGKILL, SECCOMP_RET_KILL_THREAD, true); 1017 1015 do_exit(SIGKILL); 1018 1016 } ··· 1265 1261 case SECCOMP_RET_KILL_THREAD: 1266 1262 case SECCOMP_RET_KILL_PROCESS: 1267 1263 default: 1264 + current->seccomp.mode = SECCOMP_MODE_DEAD; 1268 1265 seccomp_log(this_syscall, SIGSYS, action, true); 1269 1266 /* Dump core only if this is the last remaining thread. */ 1270 1267 if (action != SECCOMP_RET_KILL_THREAD || ··· 1314 1309 return 0; 1315 1310 case SECCOMP_MODE_FILTER: 1316 1311 return __seccomp_filter(this_syscall, sd, false); 1312 + /* Surviving SECCOMP_RET_KILL_* must be proactively impossible. */ 1313 + case SECCOMP_MODE_DEAD: 1314 + WARN_ON_ONCE(1); 1315 + do_exit(SIGKILL); 1316 + return -1; 1317 1317 default: 1318 1318 BUG(); 1319 1319 }
+3 -2
kernel/signal.c
··· 1342 1342 } 1343 1343 /* 1344 1344 * Don't clear SIGNAL_UNKILLABLE for traced tasks, users won't expect 1345 - * debugging to leave init killable. 1345 + * debugging to leave init killable. But HANDLER_EXIT is always fatal. 1346 1346 */ 1347 - if (action->sa.sa_handler == SIG_DFL && !t->ptrace) 1347 + if (action->sa.sa_handler == SIG_DFL && 1348 + (!t->ptrace || (handler == HANDLER_EXIT))) 1348 1349 t->signal->flags &= ~SIGNAL_UNKILLABLE; 1349 1350 ret = send_signal(sig, info, t, PIDTYPE_PID); 1350 1351 spin_unlock_irqrestore(&t->sighand->siglock, flags);
+7 -2
samples/seccomp/dropper.c
··· 25 25 #include <sys/prctl.h> 26 26 #include <unistd.h> 27 27 28 - static int install_filter(int nr, int arch, int error) 28 + static int install_filter(int arch, int nr, int error) 29 29 { 30 30 struct sock_filter filter[] = { 31 31 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ··· 42 42 .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), 43 43 .filter = filter, 44 44 }; 45 + if (error == -1) { 46 + struct sock_filter kill = BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL); 47 + filter[4] = kill; 48 + } 45 49 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 46 50 perror("prctl(NO_NEW_PRIVS)"); 47 51 return 1; ··· 61 57 { 62 58 if (argc < 5) { 63 59 fprintf(stderr, "Usage:\n" 64 - "dropper <syscall_nr> <arch> <errno> <prog> [<args>]\n" 60 + "dropper <arch> <syscall_nr> <errno> <prog> [<args>]\n" 65 61 "Hint: AUDIT_ARCH_I386: 0x%X\n" 66 62 " AUDIT_ARCH_X86_64: 0x%X\n" 63 + " errno == -1 means SECCOMP_RET_KILL\n" 67 64 "\n", AUDIT_ARCH_I386, AUDIT_ARCH_X86_64); 68 65 return 1; 69 66 }