]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - kernel/seccomp.c
printk: use console_trylock() in console_cpu_notify()
[mirror_ubuntu-artful-kernel.git] / kernel / seccomp.c
index f7ce79a46050e2ee6c99bcc9d2784f21721f6d25..f8f88ebcb3baa9d29c2607ff9024c43da43ab0be 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/atomic.h>
 #include <linux/audit.h>
 #include <linux/compat.h>
+#include <linux/coredump.h>
 #include <linux/sched.h>
 #include <linux/seccomp.h>
 #include <linux/slab.h>
@@ -486,6 +487,17 @@ void put_seccomp_filter(struct task_struct *tsk)
        }
 }
 
+static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason)
+{
+       memset(info, 0, sizeof(*info));
+       info->si_signo = SIGSYS;
+       info->si_code = SYS_SECCOMP;
+       info->si_call_addr = (void __user *)KSTK_EIP(current);
+       info->si_errno = reason;
+       info->si_arch = syscall_get_arch();
+       info->si_syscall = syscall;
+}
+
 /**
  * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
  * @syscall: syscall number to send to userland
@@ -496,13 +508,7 @@ void put_seccomp_filter(struct task_struct *tsk)
 static void seccomp_send_sigsys(int syscall, int reason)
 {
        struct siginfo info;
-       memset(&info, 0, sizeof(info));
-       info.si_signo = SIGSYS;
-       info.si_code = SYS_SECCOMP;
-       info.si_call_addr = (void __user *)KSTK_EIP(current);
-       info.si_errno = reason;
-       info.si_arch = syscall_get_arch();
-       info.si_syscall = syscall;
+       seccomp_init_siginfo(&info, syscall, reason);
        force_sig_info(SIGSYS, &info, current);
 }
 #endif /* CONFIG_SECCOMP_FILTER */
@@ -634,10 +640,17 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
                return 0;
 
        case SECCOMP_RET_KILL:
-       default:
+       default: {
+               siginfo_t info;
                audit_seccomp(this_syscall, SIGSYS, action);
+               /* Show the original registers in the dump. */
+               syscall_rollback(current, task_pt_regs(current));
+               /* Trigger a manual coredump since do_exit skips it. */
+               seccomp_init_siginfo(&info, this_syscall, data);
+               do_coredump(&info);
                do_exit(SIGSYS);
        }
+       }
 
        unreachable();