OSDN Git Service

BACKPORT: x86/ptrace: run seccomp after ptrace
authorKees Cook <keescook@chromium.org>
Thu, 9 Jun 2016 19:36:50 +0000 (12:36 -0700)
committerGreg Hackmann <ghackmann@google.com>
Tue, 27 Nov 2018 21:11:56 +0000 (21:11 +0000)
This moves seccomp after ptrace on x86 to that seccomp can catch changes
made by ptrace. Emulation should skip the rest of processing too.

We can get rid of test_thread_flag because there's no longer any
opportunity for seccomp to mess with ptrace state before invoking
ptrace.

Suggested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: x86@kernel.org
Cc: Andy Lutomirski <luto@kernel.org>
(cherry picked from commit 93e35efb8de45393cf61ed07f7b407629bf698ea)

Bug: 119769499
Change-Id: Ie1b9a18360799e68e22f67ce6a819c93433fdeaa
[ghackmann@google.com: adjust context]
Signed-off-by: Greg Hackmann <ghackmann@google.com>
arch/x86/entry/common.c

index 05613b8..c611c1e 100644 (file)
@@ -73,6 +73,7 @@ long syscall_trace_enter(struct pt_regs *regs)
 
        struct thread_info *ti = pt_regs_to_thread_info(regs);
        unsigned long ret = 0;
+       bool emulated = false;
        u32 work;
 
        if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
@@ -101,11 +102,19 @@ long syscall_trace_enter(struct pt_regs *regs)
        if (work & _TIF_SINGLESTEP)
                regs->flags |= X86_EFLAGS_TF;
 
+       if (unlikely(work & _TIF_SYSCALL_EMU))
+               emulated = true;
+
+       if ((emulated || (work & _TIF_SYSCALL_TRACE)) &&
+           tracehook_report_syscall_entry(regs))
+               return -1L;
+
+       if (emulated)
+               return -1L;
+
 #ifdef CONFIG_SECCOMP
        /*
-        * Do seccomp first -- it should minimize exposure of other
-        * code, and keeping seccomp fast is probably more valuable
-        * than the rest of this.
+        * Do seccomp after ptrace, to catch any tracer changes.
         */
        if (work & _TIF_SECCOMP) {
                struct seccomp_data sd;
@@ -138,13 +147,6 @@ long syscall_trace_enter(struct pt_regs *regs)
        }
 #endif
 
-       if (unlikely(work & _TIF_SYSCALL_EMU))
-               ret = -1L;
-
-       if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
-           tracehook_report_syscall_entry(regs))
-               ret = -1L;
-
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->orig_ax);