mirror of https://gitee.com/openkylin/linux.git
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. Commit0bb605c2c7
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:0bb605c2c7
("sh: Add SECCOMP_FILTER") Fixes:ab99c733ae
("sh: Make syscall tracer use tracehook notifiers, add TIF_NOTIFY_RESUME.") Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Signed-off-by: Rich Felker <dalias@libc.org>
This commit is contained in:
parent
ca6345de57
commit
b0cfc315ff
|
@ -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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue