Commit b0cfc315 authored by Rich Felker's avatar Rich Felker

sh: fix syscall tracing

Addition of SECCOMP_FILTER exposed a longstanding bug in
do_syscall_trace_enter, whereby r0 (the 5th argument register) was
mistakenly used where r3 (syscall_nr) was intended. By overwriting r0
rather than r3 with -1 when attempting to block a syscall, the
existing code would instead have caused the syscall to execute with an
argument clobbered.

Commit 0bb605c2 then introduced skipping of the syscall when
do_syscall_trace_enter returns -1, so that the return value set by
seccomp filters would not be clobbered by -ENOSYS. This eliminated the
clobbering of the 5th argument register, but instead caused syscalls
made with a 5th argument of -1 to be misinterpreted as a request by
do_syscall_trace_enter to suppress the syscall.

Fixes: 0bb605c2 ("sh: Add SECCOMP_FILTER")
Fixes: ab99c733 ("sh: Make syscall tracer use tracehook notifiers, add TIF_NOTIFY_RESUME.")
Tested-by: default avatarJohn Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Signed-off-by: default avatarRich Felker <dalias@libc.org>
parent ca6345de
...@@ -370,7 +370,6 @@ syscall_trace_entry: ...@@ -370,7 +370,6 @@ syscall_trace_entry:
nop nop
cmp/eq #-1, r0 cmp/eq #-1, r0
bt syscall_exit bt syscall_exit
mov.l r0, @(OFF_R0,r15) ! Save return value
! Reload R0-R4 from kernel stack, where the ! Reload R0-R4 from kernel stack, where the
! parent may have modified them using ! parent may have modified them using
! ptrace(POKEUSR). (Note that R0-R2 are ! ptrace(POKEUSR). (Note that R0-R2 are
......
...@@ -455,16 +455,11 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -455,16 +455,11 @@ long arch_ptrace(struct task_struct *child, long request,
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{ {
long ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs)) tracehook_report_syscall_entry(regs)) {
/* regs->regs[0] = -ENOSYS;
* Tracing decided this syscall should not happen. return -1;
* We'll return a bogus call number to get an ENOSYS }
* error, but leave the original number in regs->regs[0].
*/
ret = -1L;
if (secure_computing() == -1) if (secure_computing() == -1)
return -1; return -1;
...@@ -475,7 +470,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) ...@@ -475,7 +470,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5], audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5],
regs->regs[6], regs->regs[7]); regs->regs[6], regs->regs[7]);
return ret ?: regs->regs[0]; return 0;
} }
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment