MIPS/ptrace: Pick up ptrace/seccomp changed syscalls
authorJames Hogan <jhogan@kernel.org>
Fri, 11 Aug 2017 20:56:51 +0000 (21:56 +0100)
committerJames Hogan <jhogan@kernel.org>
Thu, 9 Nov 2017 15:13:52 +0000 (15:13 +0000)
The MIPS syscall_trace_enter() allows the system call number to be
altered or cancelled by a ptrace tracer, via the normal ptrace hook
(PTRACE_SYSCALL) and changing the system call number register on entry,
and similarly via seccomp (PTRACE_EVENT_SECCOMP when a seccomp filter
returns SECCOMP_RET_TRACE).

Be sure to update the syscall local variable if this happens, so that
seccomp will filter the correct system call number if the normal ptrace
hook changes it first, and so that if either the normal ptrace hook or
seccomp change it the correct system call number is passed to the trace
event.

This won't have any effect until the next commit, which fixes ptrace to
update thread_info::syscall.

Fixes: c2d9f1775731 ("MIPS: Fix syscall_get_nr for the syscall exit tracing.")
Signed-off-by: James Hogan <jhogan@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Lars Persson <lars.persson@axis.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Will Drewry <wad@chromium.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16996/

arch/mips/kernel/ptrace.c

index 5a09c2901a760515e5405f1cf28683b5172020a8..011993e0cce218ea0b9c831d7732947468395f24 100644 (file)
@@ -881,9 +881,11 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
 
        current_thread_info()->syscall = syscall;
 
-       if (test_thread_flag(TIF_SYSCALL_TRACE) &&
-           tracehook_report_syscall_entry(regs))
-               return -1;
+       if (test_thread_flag(TIF_SYSCALL_TRACE)) {
+               if (tracehook_report_syscall_entry(regs))
+                       return -1;
+               syscall = current_thread_info()->syscall;
+       }
 
 #ifdef CONFIG_SECCOMP
        if (unlikely(test_thread_flag(TIF_SECCOMP))) {
@@ -901,6 +903,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
                ret = __secure_computing(&sd);
                if (ret == -1)
                        return ret;
+               syscall = current_thread_info()->syscall;
        }
 #endif