From c6cfbeb4029610c8c330c312dcf4d514cc067554 Mon Sep 17 00:00:00 2001 From: Will Drewry Date: Thu, 12 Apr 2012 16:48:03 -0500 Subject: x86: Enable HAVE_ARCH_SECCOMP_FILTER Enable support for seccomp filter on x86: - syscall_get_arch() - syscall_get_arguments() - syscall_rollback() - syscall_set_return_value() - SIGSYS siginfo_t support - secure_computing is called from a ptrace_event()-safe context - secure_computing return value is checked (see below). SECCOMP_RET_TRACE and SECCOMP_RET_TRAP may result in seccomp needing to skip a system call without killing the process. This is done by returning a non-zero (-1) value from secure_computing. This change makes x86 respect that return value. To ensure that minimal kernel code is exposed, a non-zero return value results in an immediate return to user space (with an invalid syscall number). Signed-off-by: Will Drewry Reviewed-by: H. Peter Anvin Acked-by: Eric Paris Reviewed-by: Kees Cook v18: rebase and tweaked change description, acked-by v17: added reviewed by and rebased v..: all rebases since original introduction. Signed-off-by: James Morris --- arch/x86/Kconfig | 1 + arch/x86/kernel/ptrace.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1d14cc6b79a..3a41c4424a0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -82,6 +82,7 @@ config X86 select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC + select HAVE_ARCH_SECCOMP_FILTER config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 685845cf16e..13b1990c7c5 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1480,7 +1480,11 @@ long syscall_trace_enter(struct pt_regs *regs) regs->flags |= X86_EFLAGS_TF; /* do the secure computing check first */ - secure_computing(regs->orig_ax); + if (secure_computing(regs->orig_ax)) { + /* seccomp failures shouldn't expose any additional code. */ + ret = -1L; + goto out; + } if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) ret = -1L; @@ -1505,6 +1509,7 @@ long syscall_trace_enter(struct pt_regs *regs) regs->dx, regs->r10); #endif +out: return ret ?: regs->orig_ax; } -- cgit v1.2.3-70-g09d2