From 3b422564f3a3283e0c7f5fdf7cadbcd8b86a8878 Mon Sep 17 00:00:00 2001 From: Itamar Date: Sat, 15 Aug 2020 10:57:53 +0300 Subject: [PATCH] Kernel: Fix behaviour of PT_TRACEME in ptrace The behaviour of the PT_TRACEME feature has been broken for some time, this change fixes it. When this ptrace flag is used, the traced process should be paused before exiting execve. We previously were sending the SIGSTOP signal at a stage where interrupts are disabled, and the traced process continued executing normally, without pausing and waiting for the tracer. This change fixes it. --- Kernel/Arch/i386/CPU.cpp | 4 ---- Kernel/Syscalls/execve.cpp | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index 7a3a4f5159..99ff67a368 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -1190,10 +1190,6 @@ extern "C" void context_first_init(Thread* from_thread, Thread* to_thread, TrapF Scheduler::enter_current(*from_thread); - if (to_thread->process().wait_for_tracer_at_next_execve()) { - to_thread->send_urgent_signal_to_self(SIGSTOP); - } - // Since we got here and don't have Scheduler::context_switch in the // call stack (because this is the first time we switched into this // context), we need to notify the scheduler so that it can release diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 93f56ee73a..1f910795f7 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -269,6 +269,9 @@ int Process::do_exec(NonnullRefPtr main_program_description, Ve // and we don't want to deal with faults after this point. u32 new_userspace_esp = new_main_thread->make_userspace_stack_for_main_thread(move(arguments), move(environment), move(auxv)); + if (wait_for_tracer_at_next_execve()) + Thread::current()->send_urgent_signal_to_self(SIGSTOP); + // We enter a critical section here because we don't want to get interrupted between do_exec() // and Processor::assume_context() or the next context switch. // If we used an InterruptDisabler that sti()'d on exit, we might timer tick'd too soon in exec(). @@ -557,7 +560,7 @@ int Process::sys$execve(Userspace user_params) if (params.arguments.length > ARG_MAX || params.environment.length > ARG_MAX) return -E2BIG; - if (m_wait_for_tracer_at_next_execve) + if (wait_for_tracer_at_next_execve()) Thread::current()->send_urgent_signal_to_self(SIGSTOP); String path; @@ -597,5 +600,4 @@ int Process::sys$execve(Userspace user_params) ASSERT(rc < 0); // We should never continue after a successful exec! return rc; } - }