From 6132193bd43423c18c6ab8bff008946100b6afaf Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 3 Apr 2023 13:24:20 +0200 Subject: [PATCH] Kernel: Make sys$disown not require the big lock This syscall had a TOCTOU where it checked the peer's PPID before locking the protected data (where the PPID is stored). After closing the race window, we can mark the syscall as not needing the big lock. --- Kernel/API/Syscall.h | 2 +- Kernel/Syscalls/disown.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 4134eb0cc2..708e547e83 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -66,7 +66,7 @@ enum class NeedsBigProcessLock { S(create_thread, NeedsBigProcessLock::Yes) \ S(dbgputstr, NeedsBigProcessLock::No) \ S(detach_thread, NeedsBigProcessLock::Yes) \ - S(disown, NeedsBigProcessLock::Yes) \ + S(disown, NeedsBigProcessLock::No) \ S(dump_backtrace, NeedsBigProcessLock::No) \ S(dup2, NeedsBigProcessLock::No) \ S(emuctl, NeedsBigProcessLock::No) \ diff --git a/Kernel/Syscalls/disown.cpp b/Kernel/Syscalls/disown.cpp index 0be9c99ef2..685f2de69f 100644 --- a/Kernel/Syscalls/disown.cpp +++ b/Kernel/Syscalls/disown.cpp @@ -10,16 +10,17 @@ namespace Kernel { ErrorOr Process::sys$disown(ProcessID pid) { - VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); + VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::proc)); auto process = Process::from_pid_in_same_jail(pid); if (!process) return ESRCH; - if (process->ppid() != this->pid()) - return ECHILD; - process->with_mutable_protected_data([](auto& protected_data) { + TRY(process->with_mutable_protected_data([this](auto& protected_data) -> ErrorOr { + if (protected_data.ppid != this->pid()) + return ECHILD; protected_data.ppid = 0; - }); + return {}; + })); process->disowned_by_waiter(*this); return 0; }