summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-09-18 08:41:16 -0400
committerMatt Turner <mattst88@gmail.com>2010-09-18 23:08:28 -0400
commit53293638618f1a8b0b182dfedaab08b28930f992 (patch)
tree76c925826dbf71832db6212538b7a2f417008dd5 /mm
parent392fb6e35400edbee183baba24b34a0fa2053813 (diff)
downloadlinux-3.10-53293638618f1a8b0b182dfedaab08b28930f992.tar.gz
linux-3.10-53293638618f1a8b0b182dfedaab08b28930f992.tar.bz2
linux-3.10-53293638618f1a8b0b182dfedaab08b28930f992.zip
alpha: fix a 14 years old bug in sigreturn tracing
The way sigreturn() is implemented on alpha breaks PTRACE_SYSCALL, all way back to 1.3.95 when alpha has grown PTRACE_SYSCALL support. What happens is direct return to ret_from_syscall, in order to bypass mangling of a3 (error indicator) and prevent other mutilations of registers (e.g. by syscall restart). That's fine, but... the entire TIF_SYSCALL_TRACE codepath is kept separate on alpha and post-syscall stopping/notifying the tracer is after the syscall. And the normal path we are forcibly switching to doesn't have it. So we end up with *one* stop in traced sigreturn() vs. two in other syscalls. And yes, strace is visibly broken by that; try to strace the following #include <signal.h> #include <stdio.h> void f(int sig) {} main() { signal(SIGHUP, f); raise(SIGHUP); write(1, "eeeek\n", 6); } and watch the show. The close(1) = 405 in the end of strace output is coming from return value of write() (6 == __NR_close on alpha) and syscall number of exit_group() (__NR_exit_group == 405 there). The fix is fairly simple - the only thing we end up missing is the call of syscall_trace() and we can tell whether we'd been called from the SYSCALL_TRACE path by checking ra value. Since we are setting the switch_stack up (that's what sys_sigreturn() does), we have the right environment for calling syscall_trace() - just before we call undo_switch_stack() and return. Since undo_switch_stack() will overwrite s0 anyway, we can use it to store the result of "has it been called from SYSCALL_TRACE path?" check. The same thing applies in rt_sigreturn(). Tested-by: Michael Cree <mcree@orcon.net.nz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'mm')
0 files changed, 0 insertions, 0 deletions