ptrace: fix execve and return value handling (fixes strace on aarch64)

Change-Id: Icb5cb7f7e99fdb74a8628bc6b550688df5fb056b
This commit is contained in:
Balazs Gerofi
2020-02-10 03:44:43 +00:00
parent 597baf8445
commit 4bbdee395e
3 changed files with 26 additions and 11 deletions

View File

@@ -80,6 +80,7 @@
#define PT_TRACED 0x80 /* The process is ptraced */
#define PT_TRACE_EXEC 0x100 /* Trace execve(2) */
#define PT_TRACE_SYSCALL 0x200 /* Trace syscall enter */
#define PT_TRACED_AFTER_EXEC 0x1000
// ptrace(2) request
#define PTRACE_TRACEME 0
@@ -127,6 +128,7 @@
#define PTRACE_EVENT_EXEC 4
#define PTRACE_EVENT_VFORK_DONE 5
#define PTRACE_EVENT_EXIT 6
#define PTRACE_EVENT_SECCOMP 7
#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state */

View File

@@ -2312,6 +2312,7 @@ static int ptrace_report_exec(struct thread *thread)
ptrace_report_signal(thread, sig);
preempt_disable();
memcpy(&thread->ctx, &ctx, sizeof ctx);
thread->ptrace |= PT_TRACED_AFTER_EXEC;
}
return 0;
}
@@ -2593,10 +2594,6 @@ static int do_execveat(ihk_mc_user_context_t *ctx, int dirfd,
goto end;
}
if (thread->ptrace) {
arch_ptrace_syscall_event(thread, ctx, 0);
}
/* Unmap all memory areas of the process, userspace will be gone */
munmap_all();
@@ -6826,7 +6823,8 @@ static int ptrace_setoptions(int pid, int flags)
PTRACE_O_TRACEVFORK|
PTRACE_O_TRACECLONE|
PTRACE_O_TRACEEXEC|
PTRACE_O_TRACEVFORKDONE)) {
PTRACE_O_TRACEVFORKDONE|
PTRACE_O_TRACEEXIT)) {
kprintf("ptrace_setoptions: not supported flag %x\n", flags);
ret = -EINVAL;
goto out;
@@ -10005,8 +10003,17 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
cpu_enable_interrupt();
if (cpu_local_var(current)->ptrace) {
/*
* XXX: After PTRACE_EVENT_EXEC we need to report an extra SIGTRAP.
* This is a tmp fix and should be moved into ptrace_report_exec()
*/
if (cpu_local_var(current)->ptrace & PT_TRACED_AFTER_EXEC) {
arch_ptrace_syscall_event(cpu_local_var(current), ctx, 0);
cpu_local_var(current)->ptrace &= ~(PT_TRACED_AFTER_EXEC);
}
arch_ptrace_syscall_event(cpu_local_var(current),
ctx, -ENOSYS);
ctx, -ENOSYS);
num = ihk_mc_syscall_number(ctx);
}
@@ -10051,6 +10058,9 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
l = syscall_generic_forwarding(num, ctx);
}
/* Store return value so that PTRACE_GETREGSET will see it */
save_syscall_return_value(num, l);
if (cpu_local_var(current)->ptrace) {
/* arm64: The return value modified by the tracer is
* stored to x0 in the following check_signal().
@@ -10058,11 +10068,6 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
l = arch_ptrace_syscall_event(cpu_local_var(current), ctx, l);
}
/* x86_64: Setting l to rax is done in the
* following return.
*/
save_syscall_return_value(num, l);
#ifdef PROFILE_ENABLE
{
unsigned long ts = rdtsc();