aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-08-11 16:01:39 -0400
committerKees Cook <keescook@chromium.org>2017-08-14 16:46:49 -0400
commit4d3b0b05aae9ee9ce0970dc4cc0fb3fad5e85945 (patch)
tree28419965980aa84fd98bf361b52f9390fd24f534 /kernel
parentfd76875ca289a3d4722f266fd2d5532a27083903 (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.c22
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
539static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_THREAD | 540static 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();