summaryrefslogtreecommitdiff
path: root/syscall.c
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2018-01-22 03:53:43 +0100
committerDmitry V. Levin <ldv@altlinux.org>2018-01-25 01:55:08 +0000
commit1b849e23bfe96e1e6093bcc0edc7fffbeff2cb55 (patch)
tree2fe82ad10af888d2ee8308af8fc97c36b7d7c925 /syscall.c
parentceceb4dffbeaa5b0e7418458a8cae2bf8a825ea1 (diff)
downloadstrace-1b849e23bfe96e1e6093bcc0edc7fffbeff2cb55.tar.gz
Workaround stray PTRACE_EVENT_EXEC
We (apparently) had a long-standing test failure inside strace-ff.test with the symptom that it misses exit_group call. As it turned out, it was PTRACE_EVENT_EXEC followed by execve syscall exiting stop. That behaviour indeed screwed all the syscall state tracking for the tracee. Let's try to patch it up by calling trace_syscall when we receive PTRACE_EVENT_EXEC outside syscall. * defs.h (TCB_RECOVERING): New tcb flag. * strace.c (dispatch_event) <case TE_STOP_BEFORE_EXECVE>: Invoke trace_syscall with TCB_RECOVERING flag being set for the current_tcp if the tracee is not on exiting syscall. * syscall.c (get_scno): Set QUAL_RAW if we are recovering. (tamper_with_syscall_entering): Do not perform actual tampering during recovery as it's already too late. * NEWS: Mention it. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
Diffstat (limited to 'syscall.c')
-rw-r--r--syscall.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/syscall.c b/syscall.c
index 6fb111e90..ce804bf5f 100644
--- a/syscall.c
+++ b/syscall.c
@@ -572,10 +572,13 @@ tamper_with_syscall_entering(struct tcb *tcp, unsigned int *signo)
opts->first = opts->step;
- if (opts->data.flags & INJECT_F_SIGNAL)
- *signo = opts->data.signo;
- if (opts->data.flags & INJECT_F_RETVAL && !arch_set_scno(tcp, -1))
- tcp->flags |= TCB_TAMPERED;
+ if (!recovering(tcp)) {
+ if (opts->data.flags & INJECT_F_SIGNAL)
+ *signo = opts->data.signo;
+ if (opts->data.flags & INJECT_F_RETVAL &&
+ !arch_set_scno(tcp, -1))
+ tcp->flags |= TCB_TAMPERED;
+ }
return 0;
}
@@ -1256,6 +1259,15 @@ get_scno(struct tcb *tcp)
debug_msg("pid %d invalid syscall %" PRI_kld,
tcp->pid, tcp->scno);
}
+
+ /*
+ * We refrain from argument decoding during recovering
+ * as tracee memory mappings has changed and the registers
+ * are very likely pointing to garbage already.
+ */
+ if (recovering(tcp))
+ tcp->qual_flg |= QUAL_RAW;
+
return 1;
}