diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2019-11-29 14:54:06 -0800 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2019-11-29 15:47:54 -0800 |
commit | 02ce94c229251555ac726ecfebe3458ef5905fa9 (patch) | |
tree | 19e5ae21b866a950e0b42c5bc8655f5d8d1b0ef5 /arch/xtensa/kernel/ptrace.c | |
parent | ba9c1d65991a8be2e160447dd06eb803cbb9ba61 (diff) |
xtensa: fix system_call interaction with ptrace
Don't overwrite return value if system call was cancelled at entry by
ptrace. Return status code from do_syscall_trace_enter so that
pt_regs::syscall doesn't need to be changed to skip syscall.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa/kernel/ptrace.c')
-rw-r--r-- | arch/xtensa/kernel/ptrace.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index b964f0b2d886..145742d70a9f 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -542,14 +542,28 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -void do_syscall_trace_enter(struct pt_regs *regs) +void do_syscall_trace_leave(struct pt_regs *regs); +int do_syscall_trace_enter(struct pt_regs *regs) { + if (regs->syscall == NO_SYSCALL) + regs->areg[2] = -ENOSYS; + if (test_thread_flag(TIF_SYSCALL_TRACE) && - tracehook_report_syscall_entry(regs)) + tracehook_report_syscall_entry(regs)) { + regs->areg[2] = -ENOSYS; regs->syscall = NO_SYSCALL; + return 0; + } + + if (regs->syscall == NO_SYSCALL) { + do_syscall_trace_leave(regs); + return 0; + } if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, syscall_get_nr(current, regs)); + + return 1; } void do_syscall_trace_leave(struct pt_regs *regs) |