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: Roland McGrath <roland@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Roland McGrath and committed by Linus Torvalds 7d941432 897ee77b

+1 -3
-1
arch/i386/kernel/ptrace.c
··· 274 274 void ptrace_disable(struct task_struct *child) 275 275 { 276 276 clear_singlestep(child); 277 - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 278 277 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); 279 278 } 280 279
-1
arch/ia64/kernel/ptrace.c
··· 1577 1577 1578 1578 case PTRACE_DETACH: 1579 1579 /* detach a process that was attached. */ 1580 - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 1581 1580 ret = ptrace_detach(child, data); 1582 1581 goto out_tsk; 1583 1582
-1
arch/m68k/kernel/ptrace.c
··· 116 116 void ptrace_disable(struct task_struct *child) 117 117 { 118 118 singlestep_disable(child); 119 - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 120 119 } 121 120 122 121 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+1
kernel/ptrace.c
··· 233 233 234 234 /* Architecture-specific hardware disable .. */ 235 235 ptrace_disable(child); 236 + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 236 237 237 238 write_lock_irq(&tasklist_lock); 238 239 /* protect against de_thread()->release_task() */