diff options
| author | Kees Cook <keescook@chromium.org> | 2017-08-11 16:01:39 -0400 |
|---|---|---|
| committer | Kees Cook <keescook@chromium.org> | 2017-08-14 16:46:49 -0400 |
| commit | 4d3b0b05aae9ee9ce0970dc4cc0fb3fad5e85945 (patch) | |
| tree | 28419965980aa84fd98bf361b52f9390fd24f534 /kernel | |
| parent | fd76875ca289a3d4722f266fd2d5532a27083903 (diff) | |
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 <keescook@chromium.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/seccomp.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 95ac54cff00f..5c7299b9d953 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
| @@ -192,7 +192,7 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd, | |||
| 192 | 192 | ||
| 193 | /* Ensure unexpected behavior doesn't result in failing open. */ | 193 | /* Ensure unexpected behavior doesn't result in failing open. */ |
| 194 | if (unlikely(WARN_ON(f == NULL))) | 194 | if (unlikely(WARN_ON(f == NULL))) |
| 195 | return SECCOMP_RET_KILL_THREAD; | 195 | return SECCOMP_RET_KILL_PROCESS; |
| 196 | 196 | ||
| 197 | if (!sd) { | 197 | if (!sd) { |
| 198 | populate_seccomp_data(&sd_local); | 198 | populate_seccomp_data(&sd_local); |
| @@ -529,14 +529,16 @@ static void seccomp_send_sigsys(int syscall, int reason) | |||
| 529 | #endif /* CONFIG_SECCOMP_FILTER */ | 529 | #endif /* CONFIG_SECCOMP_FILTER */ |
| 530 | 530 | ||
| 531 | /* For use with seccomp_actions_logged */ | 531 | /* 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) | ||
| 533 | #define SECCOMP_LOG_TRAP (1 << 2) | 534 | #define SECCOMP_LOG_TRAP (1 << 2) |
| 534 | #define SECCOMP_LOG_ERRNO (1 << 3) | 535 | #define SECCOMP_LOG_ERRNO (1 << 3) |
| 535 | #define SECCOMP_LOG_TRACE (1 << 4) | 536 | #define SECCOMP_LOG_TRACE (1 << 4) |
| 536 | #define SECCOMP_LOG_LOG (1 << 5) | 537 | #define SECCOMP_LOG_LOG (1 << 5) |
| 537 | #define SECCOMP_LOG_ALLOW (1 << 6) | 538 | #define SECCOMP_LOG_ALLOW (1 << 6) |
| 538 | 539 | ||
| 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 | | ||
| 540 | SECCOMP_LOG_TRAP | | 542 | SECCOMP_LOG_TRAP | |
| 541 | SECCOMP_LOG_ERRNO | | 543 | SECCOMP_LOG_ERRNO | |
| 542 | SECCOMP_LOG_TRACE | | 544 | SECCOMP_LOG_TRACE | |
| @@ -563,8 +565,11 @@ static inline void seccomp_log(unsigned long syscall, long signr, u32 action, | |||
| 563 | log = seccomp_actions_logged & SECCOMP_LOG_LOG; | 565 | log = seccomp_actions_logged & SECCOMP_LOG_LOG; |
| 564 | break; | 566 | break; |
| 565 | case SECCOMP_RET_KILL_THREAD: | 567 | case SECCOMP_RET_KILL_THREAD: |
| 566 | default: | ||
| 567 | log = seccomp_actions_logged & SECCOMP_LOG_KILL_THREAD; | 568 | 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; | ||
| 568 | } | 573 | } |
| 569 | 574 | ||
| 570 | /* | 575 | /* |
| @@ -719,10 +724,12 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, | |||
| 719 | return 0; | 724 | return 0; |
| 720 | 725 | ||
| 721 | case SECCOMP_RET_KILL_THREAD: | 726 | case SECCOMP_RET_KILL_THREAD: |
| 727 | case SECCOMP_RET_KILL_PROCESS: | ||
| 722 | default: | 728 | default: |
| 723 | seccomp_log(this_syscall, SIGSYS, action, true); | 729 | seccomp_log(this_syscall, SIGSYS, action, true); |
| 724 | /* Dump core only if this is the last remaining thread. */ | 730 | /* 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) { | ||
| 726 | siginfo_t info; | 733 | siginfo_t info; |
| 727 | 734 | ||
| 728 | /* Show the original registers in the dump. */ | 735 | /* Show the original registers in the dump. */ |
| @@ -731,7 +738,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, | |||
| 731 | seccomp_init_siginfo(&info, this_syscall, data); | 738 | seccomp_init_siginfo(&info, this_syscall, data); |
| 732 | do_coredump(&info); | 739 | do_coredump(&info); |
| 733 | } | 740 | } |
| 734 | do_exit(SIGSYS); | 741 | if (action == SECCOMP_RET_KILL_PROCESS) |
| 742 | do_group_exit(SIGSYS); | ||
| 743 | else | ||
| 744 | do_exit(SIGSYS); | ||
| 735 | } | 745 | } |
| 736 | 746 | ||
| 737 | unreachable(); | 747 | unreachable(); |
