From 956314f0a185729caef7a451ab729e21d37ce02c Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Wed, 12 May 2021 21:44:07 -0700 Subject: [PATCH] Kernel: Make Process::start_tracing_from API OOM safe Modify the API so it's possible to propagate error on OOM failure. NonnullOwnPtr is not appropriate for the ThreadTracer::create() API, so switch to OwnPtr, use adopt_own_if_nonnull() to handle creation. --- Kernel/Process.cpp | 8 ++++++-- Kernel/Process.h | 2 +- Kernel/Syscalls/ptrace.cpp | 4 +++- Kernel/ThreadTracer.h | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 0805480217c593..413e25e89e28da 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -660,9 +660,13 @@ void Process::set_tty(TTY* tty) m_tty = tty; } -void Process::start_tracing_from(ProcessID tracer) +KResult Process::start_tracing_from(ProcessID tracer) { - m_tracer = ThreadTracer::create(tracer); + auto thread_tracer = ThreadTracer::create(tracer); + if (!thread_tracer) + return ENOMEM; + m_tracer = move(thread_tracer); + return KSuccess; } void Process::stop_tracing() diff --git a/Kernel/Process.h b/Kernel/Process.h index 59ffec5e841553..94cbdccf2712bd 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -241,7 +241,7 @@ class Process ThreadTracer* tracer() { return m_tracer.ptr(); } bool is_traced() const { return !!m_tracer; } - void start_tracing_from(ProcessID tracer); + KResult start_tracing_from(ProcessID tracer); void stop_tracing(); void tracer_trap(Thread&, const RegisterState&); diff --git a/Kernel/Syscalls/ptrace.cpp b/Kernel/Syscalls/ptrace.cpp index f380921834044c..1b9695f410663b 100644 --- a/Kernel/Syscalls/ptrace.cpp +++ b/Kernel/Syscalls/ptrace.cpp @@ -51,7 +51,9 @@ static KResultOr handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par if (peer_process.tracer()) { return EBUSY; } - peer_process.start_tracing_from(caller.pid()); + auto result = peer_process.start_tracing_from(caller.pid()); + if (result.is_error()) + return result.error(); ScopedSpinLock lock(peer->get_lock()); if (peer->state() != Thread::State::Stopped) { peer->send_signal(SIGSTOP, &caller); diff --git a/Kernel/ThreadTracer.h b/Kernel/ThreadTracer.h index ef2913edef0dd2..dad9a5f84ccb0a 100644 --- a/Kernel/ThreadTracer.h +++ b/Kernel/ThreadTracer.h @@ -6,8 +6,8 @@ #pragma once -#include #include +#include #include #include @@ -15,7 +15,7 @@ namespace Kernel { class ThreadTracer { public: - static NonnullOwnPtr create(ProcessID tracer) { return make(tracer); } + static OwnPtr create(ProcessID tracer) { return adopt_own_if_nonnull(new ThreadTracer(tracer)); } ProcessID tracer_pid() const { return m_tracer_pid; } bool has_pending_signal(u32 signal) const { return m_pending_signals & (1 << (signal - 1)); }