]> granicus.if.org Git - strace/commitdiff
Improve handling of unexpected tracees
authorEugene Syromyatnikov <evgsyr@gmail.com>
Fri, 4 Aug 2017 09:33:04 +0000 (11:33 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 5 Aug 2017 21:26:35 +0000 (21:26 +0000)
When receiving a ptrace stop of an unexpected child, handle it
in the most transparent way possible:
- detach it instead of PTRACE_CONT'ing;
- send it the signal with which it has been stopped.
This should hopefully help to deal with processes that have been created
with misused CLONE_PTRACE flag set.

* strace.c (maybe_allocate_tcb) <WIFSTOPPED(status) && !followfork>:
Calculate the signal similarly to the way next_event does,
forward it to the unexpected tracee, and detach the tracee.

strace.c

index 0015ad50439f2dbb41a92e116ee730fc88c31e57..b0d9b88ae7f2cbab8c307afe380e04c634a09f96 100644 (file)
--- a/strace.c
+++ b/strace.c
@@ -2082,11 +2082,19 @@ maybe_allocate_tcb(const int pid, int status)
                        error_msg("Process %d attached", pid);
                return tcp;
        } else {
-               /* This can happen if a clone call used
-                * CLONE_PTRACE itself.
+               /*
+                * This can happen if a clone call misused CLONE_PTRACE itself.
                 */
-               ptrace(PTRACE_CONT, pid, NULL, 0);
-               error_msg("Stop of unknown pid %u seen, PTRACE_CONTed it", pid);
+               unsigned int sig = WSTOPSIG(status);
+               unsigned int event = (unsigned int) status >> 16;
+
+               if (event == PTRACE_EVENT_STOP || sig == syscall_trap_sig)
+                       sig = 0;
+
+               ptrace(PTRACE_DETACH, pid, NULL, (unsigned long) sig);
+               error_msg("Detached unknown pid %d%s%s", pid,
+                         sig ? " with signal " : "",
+                         sig ? signame(sig) : "");
                return NULL;
        }
 }