Skip to content

Commit b25e671

Browse files
vapierJames Morris
authored andcommitted
seccomp: dump core when using SECCOMP_RET_KILL
The SECCOMP_RET_KILL mode is documented as immediately killing the process as if a SIGSYS had been sent and not caught (similar to a SIGKILL). However, a SIGSYS is documented as triggering a coredump which does not happen today. This has the advantage of being able to more easily debug a process that fails a seccomp filter. Today, most apps need to recompile and change their filter in order to get detailed info out, or manually run things through strace, or enable detailed kernel auditing. Now we get coredumps that fit into existing system-wide crash reporting setups. From a security pov, this shouldn't be a problem. Unhandled signals can already be sent externally which trigger a coredump independent of the status of the seccomp filter. The act of dumping core itself does not cause change in execution of the program. URL: https://crbug.com/676357 Signed-off-by: Mike Frysinger <vapier@chromium.org> Acked-by: Jorge Lucangeli Obes <jorgelo@chromium.org> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: James Morris <james.l.morris@oracle.com>
1 parent d69dece commit b25e671

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

kernel/seccomp.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/atomic.h>
1717
#include <linux/audit.h>
1818
#include <linux/compat.h>
19+
#include <linux/coredump.h>
1920
#include <linux/sched.h>
2021
#include <linux/seccomp.h>
2122
#include <linux/slab.h>
@@ -486,6 +487,17 @@ void put_seccomp_filter(struct task_struct *tsk)
486487
}
487488
}
488489

490+
static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason)
491+
{
492+
memset(info, 0, sizeof(*info));
493+
info->si_signo = SIGSYS;
494+
info->si_code = SYS_SECCOMP;
495+
info->si_call_addr = (void __user *)KSTK_EIP(current);
496+
info->si_errno = reason;
497+
info->si_arch = syscall_get_arch();
498+
info->si_syscall = syscall;
499+
}
500+
489501
/**
490502
* seccomp_send_sigsys - signals the task to allow in-process syscall emulation
491503
* @syscall: syscall number to send to userland
@@ -496,13 +508,7 @@ void put_seccomp_filter(struct task_struct *tsk)
496508
static void seccomp_send_sigsys(int syscall, int reason)
497509
{
498510
struct siginfo info;
499-
memset(&info, 0, sizeof(info));
500-
info.si_signo = SIGSYS;
501-
info.si_code = SYS_SECCOMP;
502-
info.si_call_addr = (void __user *)KSTK_EIP(current);
503-
info.si_errno = reason;
504-
info.si_arch = syscall_get_arch();
505-
info.si_syscall = syscall;
511+
seccomp_init_siginfo(&info, syscall, reason);
506512
force_sig_info(SIGSYS, &info, current);
507513
}
508514
#endif /* CONFIG_SECCOMP_FILTER */
@@ -634,10 +640,17 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
634640
return 0;
635641

636642
case SECCOMP_RET_KILL:
637-
default:
643+
default: {
644+
siginfo_t info;
638645
audit_seccomp(this_syscall, SIGSYS, action);
646+
/* Show the original registers in the dump. */
647+
syscall_rollback(current, task_pt_regs(current));
648+
/* Trigger a manual coredump since do_exit skips it. */
649+
seccomp_init_siginfo(&info, this_syscall, data);
650+
do_coredump(&info);
639651
do_exit(SIGSYS);
640652
}
653+
}
641654

642655
unreachable();
643656

0 commit comments

Comments
 (0)