diff --git a/Kernel/ProcessGroup.cpp b/Kernel/ProcessGroup.cpp index be7b389663..2e28beda95 100644 --- a/Kernel/ProcessGroup.cpp +++ b/Kernel/ProcessGroup.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, the SerenityOS developers. - * Copyright (c) 2021, Andreas Kling + * Copyright (c) 2021-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,45 +10,44 @@ namespace Kernel { -static Singleton> s_process_groups; +static Singleton> s_all_instances; -SpinlockProtected& process_groups() +SpinlockProtected& ProcessGroup::all_instances() { - return *s_process_groups; + return s_all_instances; } -ProcessGroup::~ProcessGroup() -{ - process_groups().with([&](auto& groups) { - groups.remove(*this); - }); -} +ProcessGroup::~ProcessGroup() = default; -ErrorOr> ProcessGroup::create(ProcessGroupID pgid) +ErrorOr> ProcessGroup::create_if_unused_pgid(ProcessGroupID pgid) { - auto process_group = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ProcessGroup(pgid))); - process_groups().with([&](auto& groups) { - groups.prepend(*process_group); + return all_instances().with([&](auto& all_instances) -> ErrorOr> { + for (auto& process_group : all_instances) { + if (process_group.pgid() == pgid) + return EPERM; + } + auto process_group = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ProcessGroup(pgid))); + all_instances.prepend(*process_group); + return process_group; }); - return process_group; } ErrorOr> ProcessGroup::find_or_create(ProcessGroupID pgid) { - return process_groups().with([&](auto& groups) -> ErrorOr> { - for (auto& group : groups) { + return all_instances().with([&](auto& all_instances) -> ErrorOr> { + for (auto& group : all_instances) { if (group.pgid() == pgid) return group; } auto process_group = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) ProcessGroup(pgid))); - groups.prepend(*process_group); + all_instances.prepend(*process_group); return process_group; }); } RefPtr ProcessGroup::from_pgid(ProcessGroupID pgid) { - return process_groups().with([&](auto& groups) -> RefPtr { + return all_instances().with([&](auto& groups) -> RefPtr { for (auto& group : groups) { if (group.pgid() == pgid) return &group; diff --git a/Kernel/ProcessGroup.h b/Kernel/ProcessGroup.h index 217316347c..2f74ff8d79 100644 --- a/Kernel/ProcessGroup.h +++ b/Kernel/ProcessGroup.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2020, the SerenityOS developers. + * Copyright (c) 2020-2023, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include #include #include #include +#include #include #include #include @@ -17,7 +17,7 @@ namespace Kernel { class ProcessGroup - : public AtomicRefCounted + : public ListedRefCounted , public LockWeakable { AK_MAKE_NONMOVABLE(ProcessGroup); @@ -26,7 +26,7 @@ class ProcessGroup public: ~ProcessGroup(); - static ErrorOr> create(ProcessGroupID); + static ErrorOr> create_if_unused_pgid(ProcessGroupID); static ErrorOr> find_or_create(ProcessGroupID); static RefPtr from_pgid(ProcessGroupID); @@ -38,13 +38,13 @@ private: { } - IntrusiveListNode m_list_node; ProcessGroupID m_pgid; + mutable IntrusiveListNode m_list_node; + public: - using List = IntrusiveList<&ProcessGroup::m_list_node>; + using AllInstancesList = IntrusiveList<&ProcessGroup::m_list_node>; + static SpinlockProtected& all_instances(); }; -SpinlockProtected& process_groups(); - } diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp index 32f908cf7e..bfc95acde8 100644 --- a/Kernel/Syscalls/setpgid.cpp +++ b/Kernel/Syscalls/setpgid.cpp @@ -28,16 +28,10 @@ ErrorOr 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 { - 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 { protected_data.tty = nullptr; protected_data.process_group = move(process_group);