Here is the "one swell foop" patch to cut out the old seccomp stuff, clean up the config, and replace it with the utrace-based one. The kernel/seccomp.c patch looks like a patch because it found some trivia in common, but actually it's wholly replaced with the file I posted before.
I still haven't tested it in the slightest, and only compiled it on x86-64. This presumably actually ought to be done in several smaller patches. If it should even be done this way at all. (That is, eagerly cutting out the old seccomp and leaving no seccomp option without utrace.) But here's a completeish proof of concept. Maybe someone wants to pick it up. Thanks, Roland --- [PATCH] utraceify seccomp Signed-off-by: Roland McGrath <rol...@redhat.com> --- arch/Kconfig | 4 + arch/mips/Kconfig | 18 +---- arch/mips/kernel/ptrace.c | 5 - arch/powerpc/Kconfig | 18 +---- arch/powerpc/include/asm/thread_info.h | 4 +- arch/powerpc/kernel/ptrace.c | 3 - arch/sh/Kconfig | 17 +---- arch/sh/include/asm/thread_info.h | 4 +- arch/sh/kernel/ptrace_32.c | 3 - arch/sh/kernel/ptrace_64.c | 3 - arch/sparc/include/asm/thread_info_64.h | 3 +- arch/x86/Kconfig | 17 +---- arch/x86/kernel/entry_32.S | 8 +- arch/x86/kernel/ptrace.c | 4 - include/linux/sched.h | 2 - include/linux/seccomp.h | 14 --- init/Kconfig | 18 ++++ kernel/seccomp.c | 146 ++++++++++++++++++------------- 18 files changed, 116 insertions(+), 175 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 550dab2..f809f07 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -78,6 +78,10 @@ config HAVE_KPROBES config HAVE_KRETPROBES bool +# select this if the arch has the asm/seccomp.h file. +config HAVE_SECCOMP + bool + # # An arch should select this if it provides all these things: # diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 206cb79..b7c124e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -4,6 +4,7 @@ config MIPS select HAVE_IDE select HAVE_OPROFILE select HAVE_ARCH_KGDB + select HAVE_SECCOMP # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB @@ -1949,23 +1950,6 @@ config KEXEC support. As of this writing the exact hardware interface is strongly in flux, so no good recommendation can be made. -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - default y - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - endmenu config RWSEM_GENERIC_SPINLOCK diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 054861c..2c19cfd 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -24,7 +24,6 @@ #include <linux/user.h> #include <linux/security.h> #include <linux/audit.h> -#include <linux/seccomp.h> #include <asm/byteorder.h> #include <asm/cpu.h> @@ -564,10 +563,6 @@ static inline int audit_arch(void) */ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { - /* do the secure computing check first */ - if (!entryexit) - secure_computing(regs->regs[0]); - if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), regs->regs[2]); diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 74cc312..c71ac02 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -119,6 +119,7 @@ config PPC select HAVE_ARCH_KGDB select HAVE_KRETPROBES select HAVE_ARCH_TRACEHOOK + select HAVE_SECCOMP select HAVE_LMB select HAVE_DMA_ATTRS if PPC64 select USE_GENERIC_SMP_HELPERS if SMP @@ -531,23 +532,6 @@ config ARCH_WANTS_FREEZER_CONTROL source kernel/power/Kconfig endif -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - default y - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via /proc/<pid>/seccomp, it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - endmenu config ISA_DMA_API diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 9665a26..4d30be8 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -105,7 +105,6 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SINGLESTEP 8 /* singlestepping active */ #define TIF_MEMDIE 9 -#define TIF_SECCOMP 10 /* secure computing */ #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12 /* Force successful syscall return */ #define TIF_NOTIFY_RESUME 13 /* callback before returning to user */ @@ -123,14 +122,13 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_PERFMON_CTXSW (1<<TIF_PERFMON_CTXSW) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) -#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_RESTOREALL (1<<TIF_RESTOREALL) #define _TIF_NOERROR (1<<TIF_NOERROR) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_FREEZE (1<<TIF_FREEZE) #define _TIF_RUNLATCH (1<<TIF_RUNLATCH) #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) -#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP) +#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_RESUME) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 3635be6..f5657c3 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -27,7 +27,6 @@ #include <linux/user.h> #include <linux/security.h> #include <linux/signal.h> -#include <linux/seccomp.h> #include <linux/audit.h> #ifdef CONFIG_PPC32 #include <linux/module.h> @@ -1021,8 +1020,6 @@ long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; - secure_computing(regs->gpr[0]); - if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) /* diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index ebabe51..5786e77 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -14,6 +14,7 @@ config SUPERH select HAVE_GENERIC_DMA_COHERENT select HAVE_IOREMAP_PROT if MMU select HAVE_ARCH_TRACEHOOK + select HAVE_SECCOMP help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast @@ -521,22 +522,6 @@ config CRASH_DUMP For more details see Documentation/kdump/kdump.txt -config SECCOMP - bool "Enable seccomp to safely compute untrusted bytecode" - depends on PROC_FS - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl, it cannot be disabled and the task is only - allowed to execute a few safe syscalls defined by each seccomp - mode. - - If unsure, say N. - config SMP bool "Symmetric multi-processing support" depends on SYS_SUPPORTS_SMP diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index f09ac48..e1da51a 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -114,7 +114,6 @@ extern void free_thread_info(struct thread_info *ti); #define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */ #define TIF_SINGLESTEP 4 /* singlestepping active */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ -#define TIF_SECCOMP 6 /* secure computing */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ @@ -127,7 +126,6 @@ extern void free_thread_info(struct thread_info *ti); #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_USEDFPU (1 << TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) @@ -141,7 +139,7 @@ extern void free_thread_info(struct thread_info *ti); /* work to do in syscall trace */ #define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \ - _TIF_SYSCALL_AUDIT | _TIF_SECCOMP) + _TIF_SYSCALL_AUDIT) /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \ diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 29ca09d..c83d0fe 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -22,7 +22,6 @@ #include <linux/signal.h> #include <linux/io.h> #include <linux/audit.h> -#include <linux/seccomp.h> #include <linux/tracehook.h> #include <linux/elf.h> #include <linux/regset.h> @@ -438,8 +437,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; - secure_computing(regs->regs[0]); - if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) /* diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 6950974..e65dbe0 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -27,7 +27,6 @@ #include <linux/signal.h> #include <linux/syscalls.h> #include <linux/audit.h> -#include <linux/seccomp.h> #include <linux/tracehook.h> #include <linux/elf.h> #include <linux/regset.h> @@ -427,8 +426,6 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs) { long long ret = 0; - secure_computing(regs->regs[9]); - if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) /* diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 639ac80..b303b93 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -227,7 +227,7 @@ register struct thread_info *current_thread_info_reg asm("g6"); /* flag bit 6 is available */ #define TIF_32BIT 7 /* 32-bit binary */ /* flag bit 8 is available */ -#define TIF_SECCOMP 9 /* secure computing */ +/* flag bit 9 is available */ #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */ /* flag bit 11 is available */ /* NOTE: Thread flags >= 12 should be ones we have no interest @@ -246,7 +246,6 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define _TIF_PERFCTR (1<<TIF_PERFCTR) #define _TIF_UNALIGNED (1<<TIF_UNALIGNED) #define _TIF_32BIT (1<<TIF_32BIT) -#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index bc2fbad..25ec433 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -37,6 +37,7 @@ config X86 select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER select HAVE_ARCH_TRACEHOOK + select HAVE_SECCOMP select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_EFFICIENT_UNALIGNED_ACCESS select USER_STACKTRACE_SUPPORT @@ -1324,22 +1325,6 @@ config EFI resultant kernel should continue to boot on existing non-EFI platforms. -config SECCOMP - def_bool y - prompt "Enable seccomp to safely compute untrusted bytecode" - help - This kernel feature is useful for number crunching applications - that may need to compute untrusted bytecode during their - execution. By using pipes or other transports made available to - the process as file descriptors supporting the read/write - syscalls, it's possible to isolate those applications in - their own address space using seccomp. Once seccomp is - enabled via prctl(PR_SET_SECCOMP), it cannot be disabled - and the task is only allowed to execute a few safe syscalls - defined by each seccomp mode. - - If unsure, say Y. Only embedded should say N here. - config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" depends on X86_64 && EXPERIMENTAL && BROKEN diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 4646902..21e7046 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -341,8 +341,7 @@ sysenter_past_esp: GET_THREAD_INFO(%ebp) - /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ - testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) + testb $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz sysenter_audit sysenter_do_call: cmpl $(nr_syscalls), %eax @@ -366,7 +365,7 @@ sysenter_exit: #ifdef CONFIG_AUDITSYSCALL sysenter_audit: - testw $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) + testb $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) jnz syscall_trace_entry addl $4,%esp CFI_ADJUST_CFA_OFFSET -4 @@ -420,8 +419,7 @@ ENTRY(system_call) SAVE_ALL GET_THREAD_INFO(%ebp) # system call tracing in operation / emulation - /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ - testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) + testb $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz syscall_trace_entry cmpl $(nr_syscalls), %eax jae syscall_badsys diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 06ca07f..0d6bcff 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -19,7 +19,6 @@ #include <linux/elf.h> #include <linux/security.h> #include <linux/audit.h> -#include <linux/seccomp.h> #include <linux/signal.h> #include <asm/uaccess.h> @@ -1411,9 +1410,6 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) if (test_thread_flag(TIF_SINGLESTEP)) regs->flags |= X86_EFLAGS_TF; - /* do the secure computing check first */ - secure_computing(regs->orig_ax); - if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) ret = -1L; diff --git a/include/linux/sched.h b/include/linux/sched.h index 786ef2d..4a22d98 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -76,7 +76,6 @@ struct sched_param { #include <linux/percpu.h> #include <linux/topology.h> #include <linux/proportions.h> -#include <linux/seccomp.h> #include <linux/rcupdate.h> #include <linux/rtmutex.h> @@ -1286,7 +1285,6 @@ struct task_struct { uid_t loginuid; unsigned int sessionid; #endif - seccomp_t seccomp; #ifdef CONFIG_UTRACE struct utrace utrace; diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 262a8dc..02d7adb 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -4,27 +4,13 @@ #ifdef CONFIG_SECCOMP -#include <linux/thread_info.h> #include <asm/seccomp.h> -typedef struct { int mode; } seccomp_t; - -extern void __secure_computing(int); -static inline void secure_computing(int this_syscall) -{ - if (unlikely(test_thread_flag(TIF_SECCOMP))) - __secure_computing(this_syscall); -} - extern long prctl_get_seccomp(void); extern long prctl_set_seccomp(unsigned long); #else /* CONFIG_SECCOMP */ -typedef struct { } seccomp_t; - -#define secure_computing(x) do { } while (0) - static inline long prctl_get_seccomp(void) { return -EINVAL; diff --git a/init/Kconfig b/init/Kconfig index 4b5ab3e..bc90ad3 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1069,6 +1069,24 @@ menuconfig UTRACE kernel interface exported to kernel modules, to track events in user threads, extract and change user thread state. +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + default y if UTRACE + depends on UTRACE + depends on HAVE_SECCOMP + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via prctl(PR_SET_SECCOMP), it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + source "block/Kconfig" config PREEMPT_NOTIFIERS diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 57d4b13..f14d1fd 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -1,86 +1,108 @@ -/* - * linux/kernel/seccomp.c - * - * Copyright 2004-2005 Andrea Arcangeli <and...@cpushare.com> - * - * This defines a simple but solid secure-computing mode. - */ - #include <linux/seccomp.h> -#include <linux/sched.h> +#include <linux/utrace.h> +#include <linux/signal.h> +#include <linux/err.h> #include <linux/compat.h> - -/* #define SECCOMP_DEBUG 1 */ -#define NR_SECCOMP_MODES 1 +#include <linux/prctl.h> +#include <asm/syscall.h> /* - * Secure computing mode 1 allows only read/write/exit/sigreturn. - * To be fully secure this must be combined with rlimit - * to limit the stack allocations too. + * If it's an accepted syscall, run it normally. + * If not, send ourselves a SIGKILL and abort the syscall. */ -static int mode1_syscalls[] = { - __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, - 0, /* null terminated */ -}; +static u32 secure_syscall_entry(u32 action, + struct utrace_engine *engine, + struct task_struct *task, + struct pt_regs *regs) +{ + int callno = syscall_get_nr(task, regs); #ifdef CONFIG_COMPAT -static int mode1_syscalls_32[] = { - __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, - 0, /* null terminated */ -}; + if (is_compat_task()) + switch (callno) { + case __NR_seccomp_read_32: + case __NR_seccomp_write_32: + case __NR_seccomp_exit_32: + case __NR_seccomp_sigreturn_32: + return UTRACE_RESUME | UTRACE_SYSCALL_RUN; + } + else #endif + switch (callno) { + case __NR_seccomp_read: + case __NR_seccomp_write: + case __NR_seccomp_exit: + case __NR_seccomp_sigreturn: + return UTRACE_RESUME | UTRACE_SYSCALL_RUN; + } -void __secure_computing(int this_syscall) + force_sig(SIGKILL, task); + return UTRACE_RESUME | UTRACE_SYSCALL_ABORT; +} + +static const struct utrace_engine_ops secure_syscall_ops = { - int mode = current->seccomp.mode; - int * syscall; + .report_syscall_entry = secure_syscall_entry +}; - switch (mode) { - case 1: - syscall = mode1_syscalls; -#ifdef CONFIG_COMPAT - if (is_compat_task()) - syscall = mode1_syscalls_32; -#endif - do { - if (*syscall == this_syscall) - return; - } while (*++syscall); - break; - default: - BUG(); +/* + * Set up a utrace engine to call secure_syscall_entry() for each system call. + * Also act like prctl(PR_SET_TSC, PR_TSC_SIGSEGV). + */ +static int enable_secure_syscall(void) +{ + struct utrace_engine *engine; + int ret; + + engine = utrace_attach_task(current, + UTRACE_ATTACH_CREATE | + UTRACE_ATTACH_EXCLUSIVE | + UTRACE_ATTACH_MATCH_OPS, + &secure_syscall_ops, NULL); + if (IS_ERR(engine)) { + ret = PTR_ERR(engine); + return ret == -EEXIST ? -EPERM : ret; } -#ifdef SECCOMP_DEBUG - dump_stack(); + ret = utrace_set_events(current, engine, UTRACE_EVENT(SYSCALL_ENTRY)); + WARN_ON(ret); /* Should never happen on current. */ + + /* + * This is the only outside ref on the engine. + * The engine dies automatically when this task gets reaped. + */ + utrace_engine_put(engine); + +#ifdef SET_TSC_CTL + if (!ret) + SET_TSC_CTL(PR_TSC_SIGSEGV); #endif - do_exit(SIGKILL); + + return ret; } long prctl_get_seccomp(void) { - return current->seccomp.mode; + struct utrace_engine *engine = utrace_attach_task( + current, UTRACE_ATTACH_MATCH_OPS, &secure_syscall_ops, NULL); + + if (engine == ERR_PTR(-ENOENT)) + return 0; + + if (!IS_ERR(engine)) + /* + * I wonder how he managed to call prctl() with it enabled. + * That should be impossible. + */ + return 1; + + return PTR_ERR(engine); } long prctl_set_seccomp(unsigned long seccomp_mode) { - long ret; - - /* can set it only once to be even more secure */ - ret = -EPERM; - if (unlikely(current->seccomp.mode)) - goto out; - - ret = -EINVAL; - if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) { - current->seccomp.mode = seccomp_mode; - set_thread_flag(TIF_SECCOMP); -#ifdef TIF_NOTSC - disable_TSC(); -#endif - ret = 0; - } + if (seccomp_mode != 1) + return -EINVAL; - out: - return ret; + return enable_secure_syscall(); }