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.
This commit is contained in:
Andreas Kling 2023-04-03 13:24:20 +02:00
commit 6132193bd4
Notes: sideshowbarker 2024-07-17 08:36:27 +09:00
2 changed files with 7 additions and 6 deletions

View file

@ -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) \

View file

@ -10,16 +10,17 @@ namespace Kernel {
ErrorOr<FlatPtr> 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<void> {
if (protected_data.ppid != this->pid())
return ECHILD;
protected_data.ppid = 0;
});
return {};
}));
process->disowned_by_waiter(*this);
return 0;
}