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>
This commit is contained in:
parent
fd76875ca2
commit
4d3b0b05aa
|
@ -22,18 +22,20 @@
|
||||||
/*
|
/*
|
||||||
* All BPF programs must return a 32-bit value.
|
* All BPF programs must return a 32-bit value.
|
||||||
* The bottom 16-bits are for optional return data.
|
* The bottom 16-bits are for optional return data.
|
||||||
* The upper 16-bits are ordered from least permissive values to most.
|
* The upper 16-bits are ordered from least permissive values to most,
|
||||||
|
* as a signed value (so 0x8000000 is negative).
|
||||||
*
|
*
|
||||||
* The ordering ensures that a min_t() over composed return values always
|
* The ordering ensures that a min_t() over composed return values always
|
||||||
* selects the least permissive choice.
|
* selects the least permissive choice.
|
||||||
*/
|
*/
|
||||||
#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */
|
#define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */
|
||||||
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
|
#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */
|
||||||
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
|
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
|
||||||
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
|
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
|
||||||
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
|
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
|
||||||
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
|
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
|
||||||
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
|
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
|
||||||
|
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
|
||||||
|
|
||||||
/* Masks for the return value sections. */
|
/* Masks for the return value sections. */
|
||||||
#define SECCOMP_RET_ACTION 0x7fff0000U
|
#define SECCOMP_RET_ACTION 0x7fff0000U
|
||||||
|
|
|
@ -192,7 +192,7 @@ static u32 seccomp_run_filters(const struct seccomp_data *sd,
|
||||||
|
|
||||||
/* Ensure unexpected behavior doesn't result in failing open. */
|
/* Ensure unexpected behavior doesn't result in failing open. */
|
||||||
if (unlikely(WARN_ON(f == NULL)))
|
if (unlikely(WARN_ON(f == NULL)))
|
||||||
return SECCOMP_RET_KILL_THREAD;
|
return SECCOMP_RET_KILL_PROCESS;
|
||||||
|
|
||||||
if (!sd) {
|
if (!sd) {
|
||||||
populate_seccomp_data(&sd_local);
|
populate_seccomp_data(&sd_local);
|
||||||
|
@ -529,14 +529,16 @@ static void seccomp_send_sigsys(int syscall, int reason)
|
||||||
#endif /* CONFIG_SECCOMP_FILTER */
|
#endif /* CONFIG_SECCOMP_FILTER */
|
||||||
|
|
||||||
/* For use with seccomp_actions_logged */
|
/* For use with seccomp_actions_logged */
|
||||||
#define SECCOMP_LOG_KILL_THREAD (1 << 0)
|
#define SECCOMP_LOG_KILL_PROCESS (1 << 0)
|
||||||
|
#define SECCOMP_LOG_KILL_THREAD (1 << 1)
|
||||||
#define SECCOMP_LOG_TRAP (1 << 2)
|
#define SECCOMP_LOG_TRAP (1 << 2)
|
||||||
#define SECCOMP_LOG_ERRNO (1 << 3)
|
#define SECCOMP_LOG_ERRNO (1 << 3)
|
||||||
#define SECCOMP_LOG_TRACE (1 << 4)
|
#define SECCOMP_LOG_TRACE (1 << 4)
|
||||||
#define SECCOMP_LOG_LOG (1 << 5)
|
#define SECCOMP_LOG_LOG (1 << 5)
|
||||||
#define SECCOMP_LOG_ALLOW (1 << 6)
|
#define SECCOMP_LOG_ALLOW (1 << 6)
|
||||||
|
|
||||||
static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_THREAD |
|
static u32 seccomp_actions_logged = SECCOMP_LOG_KILL_PROCESS |
|
||||||
|
SECCOMP_LOG_KILL_THREAD |
|
||||||
SECCOMP_LOG_TRAP |
|
SECCOMP_LOG_TRAP |
|
||||||
SECCOMP_LOG_ERRNO |
|
SECCOMP_LOG_ERRNO |
|
||||||
SECCOMP_LOG_TRACE |
|
SECCOMP_LOG_TRACE |
|
||||||
|
@ -563,8 +565,11 @@ static inline void seccomp_log(unsigned long syscall, long signr, u32 action,
|
||||||
log = seccomp_actions_logged & SECCOMP_LOG_LOG;
|
log = seccomp_actions_logged & SECCOMP_LOG_LOG;
|
||||||
break;
|
break;
|
||||||
case SECCOMP_RET_KILL_THREAD:
|
case SECCOMP_RET_KILL_THREAD:
|
||||||
default:
|
|
||||||
log = seccomp_actions_logged & SECCOMP_LOG_KILL_THREAD;
|
log = seccomp_actions_logged & SECCOMP_LOG_KILL_THREAD;
|
||||||
|
break;
|
||||||
|
case SECCOMP_RET_KILL_PROCESS:
|
||||||
|
default:
|
||||||
|
log = seccomp_actions_logged & SECCOMP_LOG_KILL_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -719,10 +724,12 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SECCOMP_RET_KILL_THREAD:
|
case SECCOMP_RET_KILL_THREAD:
|
||||||
|
case SECCOMP_RET_KILL_PROCESS:
|
||||||
default:
|
default:
|
||||||
seccomp_log(this_syscall, SIGSYS, action, true);
|
seccomp_log(this_syscall, SIGSYS, action, true);
|
||||||
/* Dump core only if this is the last remaining thread. */
|
/* Dump core only if this is the last remaining thread. */
|
||||||
if (get_nr_threads(current) == 1) {
|
if (action == SECCOMP_RET_KILL_PROCESS ||
|
||||||
|
get_nr_threads(current) == 1) {
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
|
|
||||||
/* Show the original registers in the dump. */
|
/* Show the original registers in the dump. */
|
||||||
|
@ -731,7 +738,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
|
||||||
seccomp_init_siginfo(&info, this_syscall, data);
|
seccomp_init_siginfo(&info, this_syscall, data);
|
||||||
do_coredump(&info);
|
do_coredump(&info);
|
||||||
}
|
}
|
||||||
do_exit(SIGSYS);
|
if (action == SECCOMP_RET_KILL_PROCESS)
|
||||||
|
do_group_exit(SIGSYS);
|
||||||
|
else
|
||||||
|
do_exit(SIGSYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable();
|
unreachable();
|
||||||
|
|
Loading…
Reference in New Issue