diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2018-01-22 03:53:43 +0100 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2018-01-25 01:55:08 +0000 |
commit | 1b849e23bfe96e1e6093bcc0edc7fffbeff2cb55 (patch) | |
tree | 2fe82ad10af888d2ee8308af8fc97c36b7d7c925 /syscall.c | |
parent | ceceb4dffbeaa5b0e7418458a8cae2bf8a825ea1 (diff) | |
download | strace-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.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -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; } |