Commit 7d941432 authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds

Fix spurious syscall tracing after PTRACE_DETACH + PTRACE_ATTACH

When PTRACE_SYSCALL was used and then PTRACE_DETACH is used, the
TIF_SYSCALL_TRACE flag is left set on the formerly-traced task.  This
means that when a new tracer comes along and does PTRACE_ATTACH, it's
possible he gets a syscall tracing stop even though he's never used
PTRACE_SYSCALL.  This happens if the task was in the middle of a system
call when the second PTRACE_ATTACH was done.  The symptom is an
unexpected SIGTRAP when the tracer thinks that only SIGSTOP should have
been provoked by his ptrace calls so far.

A few machines already fixed this in ptrace_disable (i386, ia64, m68k).
But all other machines do not, and still have this bug.  On x86_64, this
constitutes a regression in IA32 compatibility support.

Since all machines now use TIF_SYSCALL_TRACE for this, I put the
clearing of TIF_SYSCALL_TRACE in the generic ptrace_detach code rather
than adding it to every other machine's ptrace_disable.
Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 897ee77b
...@@ -274,7 +274,6 @@ static void clear_singlestep(struct task_struct *child) ...@@ -274,7 +274,6 @@ static void clear_singlestep(struct task_struct *child)
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
clear_singlestep(child); clear_singlestep(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
} }
......
...@@ -1577,7 +1577,6 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) ...@@ -1577,7 +1577,6 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
case PTRACE_DETACH: case PTRACE_DETACH:
/* detach a process that was attached. */ /* detach a process that was attached. */
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
ret = ptrace_detach(child, data); ret = ptrace_detach(child, data);
goto out_tsk; goto out_tsk;
......
...@@ -116,7 +116,6 @@ static inline void singlestep_disable(struct task_struct *child) ...@@ -116,7 +116,6 @@ static inline void singlestep_disable(struct task_struct *child)
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
singlestep_disable(child); singlestep_disable(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
} }
long arch_ptrace(struct task_struct *child, long request, long addr, long data) long arch_ptrace(struct task_struct *child, long request, long addr, long data)
......
...@@ -233,6 +233,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data) ...@@ -233,6 +233,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data)
/* Architecture-specific hardware disable .. */ /* Architecture-specific hardware disable .. */
ptrace_disable(child); ptrace_disable(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
write_lock_irq(&tasklist_lock); write_lock_irq(&tasklist_lock);
/* protect against de_thread()->release_task() */ /* protect against de_thread()->release_task() */
......
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