Skip to content

Commit 4d3b0b0

Browse files
committed
seccomp: Introduce SECCOMP_RET_KILL_PROCESS
This introduces the BPF return value for SECCOMP_RET_KILL_PROCESS to kill an entire process. This cannot yet be reached by seccomp, but it changes the default-kill behavior (for unknown return values) from kill-thread to kill-process. Signed-off-by: Kees Cook <[email protected]>
1 parent fd76875 commit 4d3b0b0

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

include/uapi/linux/seccomp.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,20 @@
2222
/*
2323
* All BPF programs must return a 32-bit value.
2424
* The bottom 16-bits are for optional return data.
25-
* The upper 16-bits are ordered from least permissive values to most.
25+
* The upper 16-bits are ordered from least permissive values to most,
26+
* as a signed value (so 0x8000000 is negative).
2627
*
2728
* The ordering ensures that a min_t() over composed return values always
2829
* selects the least permissive choice.
2930
*/
30-
#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */
31-
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
32-
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
33-
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
34-
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
35-
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
36-
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
31+
#define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */
32+
#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */
33+
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
34+
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
35+
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
36+
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
37+
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
38+
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
3739

3840
/* Masks for the return value sections. */
3941
#define SECCOMP_RET_ACTION 0x7fff0000U

kernel/seccomp.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd,
192192

193193
/* Ensure unexpected behavior doesn't result in failing open. */
194194
if (unlikely(WARN_ON(f == NULL)))
195-
return SECCOMP_RET_KILL_THREAD;
195+
return SECCOMP_RET_KILL_PROCESS;
196196

197197
if (!sd) {
198198
populate_seccomp_data(&sd_local);
@@ -529,14 +529,16 @@ static void seccomp_send_sigsys(int syscall, int reason)
529529
#endif /* CONFIG_SECCOMP_FILTER */
530530

531531
/* For use with seccomp_actions_logged */
532-
#define SECCOMP_LOG_KILL_THREAD (1 << 0)
532+
#define SECCOMP_LOG_KILL_PROCESS (1 << 0)
533+
#define SECCOMP_LOG_KILL_THREAD (1 << 1)
533534
#define SECCOMP_LOG_TRAP (1 << 2)
534535
#define SECCOMP_LOG_ERRNO (1 << 3)
535536
#define SECCOMP_LOG_TRACE (1 << 4)
536537
#define SECCOMP_LOG_LOG (1 << 5)
537538
#define SECCOMP_LOG_ALLOW (1 << 6)
538539

539-
static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_THREAD |
540+
static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_PROCESS |
541+
SECCOMP_LOG_KILL_THREAD |
540542
SECCOMP_LOG_TRAP |
541543
SECCOMP_LOG_ERRNO |
542544
SECCOMP_LOG_TRACE |
@@ -563,8 +565,11 @@ static inline void seccomp_log(unsigned long syscall, long signr, u32 action,
563565
log = seccomp_actions_logged & SECCOMP_LOG_LOG;
564566
break;
565567
case SECCOMP_RET_KILL_THREAD:
566-
default:
567568
log = seccomp_actions_logged & SECCOMP_LOG_KILL_THREAD;
569+
break;
570+
case SECCOMP_RET_KILL_PROCESS:
571+
default:
572+
log = seccomp_actions_logged & SECCOMP_LOG_KILL_PROCESS;
568573
}
569574

570575
/*
@@ -719,10 +724,12 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
719724
return 0;
720725

721726
case SECCOMP_RET_KILL_THREAD:
727+
case SECCOMP_RET_KILL_PROCESS:
722728
default:
723729
seccomp_log(this_syscall, SIGSYS, action, true);
724730
/* Dump core only if this is the last remaining thread. */
725-
if (get_nr_threads(current) == 1) {
731+
if (action == SECCOMP_RET_KILL_PROCESS ||
732+
get_nr_threads(current) == 1) {
726733
siginfo_t info;
727734

728735
/* Show the original registers in the dump. */
@@ -731,7 +738,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
731738
seccomp_init_siginfo(&info, this_syscall, data);
732739
do_coredump(&info);
733740
}
734-
do_exit(SIGSYS);
741+
if (action == SECCOMP_RET_KILL_PROCESS)
742+
do_group_exit(SIGSYS);
743+
else
744+
do_exit(SIGSYS);
735745
}
736746

737747
unreachable();

0 commit comments

Comments
 (0)