From 638fe6f84af38053d3817eace69ea332d390acd3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 27 Jan 2020 13:48:54 +0100 Subject: [PATCH] Kernel: Disable interrupts while looking into the thread table There was a race window in a bunch of syscalls between calling Thread::from_tid() and checking if the found thread was in the same process as the calling thread. If the found thread object was destroyed at that point, there was a use-after-free that could be exploited by filling the kernel heap with something that looked like a thread object. --- Kernel/Process.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 5a52bc26cc..47bb4d6a6d 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -3633,6 +3633,7 @@ void Process::sys$exit_thread(void* exit_value) int Process::sys$detach_thread(int tid) { REQUIRE_PROMISE(thread); + InterruptDisabler disabler; auto* thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) return -ESRCH; @@ -3650,6 +3651,7 @@ int Process::sys$join_thread(int tid, void** exit_value) if (exit_value && !validate_write_typed(exit_value)) return -EFAULT; + InterruptDisabler disabler; auto* thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) return -ESRCH; @@ -3701,6 +3703,7 @@ int Process::sys$set_thread_name(int tid, const char* user_name, size_t user_nam if (name.length() > max_thread_name_size) return -EINVAL; + InterruptDisabler disabler; auto* thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) return -ESRCH; @@ -3717,6 +3720,7 @@ int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size) if (!validate_write(buffer, buffer_size)) return -EFAULT; + InterruptDisabler disabler; auto* thread = Thread::from_tid(tid); if (!thread || thread->pid() != pid()) return -ESRCH;