1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:47:45 +00:00

Kernel: Make ProcessGroup a ListedRefCounted and fix two races

This closes two race windows:

- ProcessGroup removed itself from the "all process groups" list in its
  destructor. It was possible to walk the list between the last unref()
  and the destructor invocation, and grab a pointer to a ProcessGroup
  that was about to get deleted.

- sys$setsid() could end up creating a process group that already
  existed, as there was a race window between checking if the PGID
  is used, and actually creating a ProcessGroup with that PGID.
This commit is contained in:
Andreas Kling 2023-04-04 16:38:46 +02:00
parent 37bfc36601
commit 3e30d9bc99
3 changed files with 29 additions and 36 deletions

View file

@ -28,16 +28,10 @@ ErrorOr<FlatPtr> Process::sys$setsid()
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
TRY(require_promise(Pledge::proc));
bool found_process_with_same_pgid_as_my_pid = false;
TRY(Process::for_each_in_pgrp_in_same_jail(pid().value(), [&](auto&) -> ErrorOr<void> {
found_process_with_same_pgid_as_my_pid = true;
return {};
}));
if (found_process_with_same_pgid_as_my_pid)
return EPERM;
// Create a new Session and a new ProcessGroup.
auto process_group = TRY(ProcessGroup::create(ProcessGroupID(pid().value())));
// NOTE: ProcessGroup::create_if_unused_pgid() will fail with EPERM
// if a process group with the same PGID already exists.
auto process_group = TRY(ProcessGroup::create_if_unused_pgid(ProcessGroupID(pid().value())));
return with_mutable_protected_data([&](auto& protected_data) -> ErrorOr<FlatPtr> {
protected_data.tty = nullptr;
protected_data.process_group = move(process_group);