From 9782f1fbb8f4cc137e2ea966a40c620505a5ead7 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 9 Jun 2016 12:36:50 -0700 Subject: [PATCH] BACKPORT: x86/ptrace: run seccomp after ptrace 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 Signed-off-by: Kees Cook Cc: x86@kernel.org Cc: Andy Lutomirski (cherry picked from commit 93e35efb8de45393cf61ed07f7b407629bf698ea) Bug: 119769499 Change-Id: Ie1b9a18360799e68e22f67ce6a819c93433fdeaa [ghackmann@google.com: adjust context] Signed-off-by: Greg Hackmann Signed-off-by: Amit Pundir --- arch/x86/entry/common.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 05613b8da509..c611c1ed064b 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -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);