diff options
-rw-r--r-- | Kernel/Arch/aarch64/init.cpp | 3 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/init.cpp | 2 | ||||
-rw-r--r-- | Kernel/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/SysFS/Subsystems/Kernel/Jails.cpp | 6 | ||||
-rw-r--r-- | Kernel/Jail.cpp | 59 | ||||
-rw-r--r-- | Kernel/Jail.h | 24 | ||||
-rw-r--r-- | Kernel/JailManagement.cpp | 76 | ||||
-rw-r--r-- | Kernel/JailManagement.h | 42 | ||||
-rw-r--r-- | Kernel/Process.cpp | 130 | ||||
-rw-r--r-- | Kernel/Process.h | 28 | ||||
-rw-r--r-- | Kernel/ProcessList.cpp | 16 | ||||
-rw-r--r-- | Kernel/Syscalls/execve.cpp | 6 | ||||
-rw-r--r-- | Kernel/Syscalls/fork.cpp | 21 | ||||
-rw-r--r-- | Kernel/Syscalls/jail.cpp | 13 |
14 files changed, 214 insertions, 214 deletions
diff --git a/Kernel/Arch/aarch64/init.cpp b/Kernel/Arch/aarch64/init.cpp index 7a690cce94..326b32051e 100644 --- a/Kernel/Arch/aarch64/init.cpp +++ b/Kernel/Arch/aarch64/init.cpp @@ -26,7 +26,6 @@ #include <Kernel/Devices/DeviceManagement.h> #include <Kernel/FileSystem/VirtualFileSystem.h> #include <Kernel/Graphics/Console/BootFramebufferConsole.h> -#include <Kernel/JailManagement.h> #include <Kernel/KSyms.h> #include <Kernel/Memory/MemoryManager.h> #include <Kernel/Panic.h> @@ -175,8 +174,6 @@ extern "C" [[noreturn]] void init() Processor::disable_interrupts(); TimeManagement::initialize(0); - JailManagement::the(); - Process::initialize(); Scheduler::initialize(); diff --git a/Kernel/Arch/x86_64/init.cpp b/Kernel/Arch/x86_64/init.cpp index cc2b2757c2..4188128d9e 100644 --- a/Kernel/Arch/x86_64/init.cpp +++ b/Kernel/Arch/x86_64/init.cpp @@ -38,7 +38,6 @@ #include <Kernel/Graphics/Console/VGATextModeConsole.h> #include <Kernel/Graphics/GraphicsManagement.h> #include <Kernel/Heap/kmalloc.h> -#include <Kernel/JailManagement.h> #include <Kernel/KSyms.h> #include <Kernel/Memory/MemoryManager.h> #include <Kernel/Multiboot.h> @@ -231,7 +230,6 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info) __stack_chk_guard = get_fast_random<uintptr_t>(); - JailManagement::the(); Process::initialize(); Scheduler::initialize(); diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index f880747190..7168aa494e 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -93,7 +93,6 @@ set(KERNEL_SOURCES Graphics/VirtIOGPU/GraphicsAdapter.cpp IOWindow.cpp Jail.cpp - JailManagement.cpp SanCov.cpp Storage/ATA/AHCI/Controller.cpp Storage/ATA/AHCI/Port.cpp @@ -256,6 +255,7 @@ set(KERNEL_SOURCES PerformanceEventBuffer.cpp Process.cpp ProcessGroup.cpp + ProcessList.cpp Random.cpp Scheduler.cpp ScopedCritical.cpp diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Jails.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Jails.cpp index dbe37ce092..7c8f24f7c6 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Jails.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Jails.cpp @@ -1,12 +1,12 @@ /* - * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il> * * SPDX-License-Identifier: BSD-2-Clause */ #include <AK/JsonObjectSerializer.h> #include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Jails.h> -#include <Kernel/JailManagement.h> +#include <Kernel/Jail.h> #include <Kernel/Sections.h> namespace Kernel { @@ -24,7 +24,7 @@ UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSJails> SysFSJails::must_create(SysFSDire ErrorOr<void> SysFSJails::try_generate(KBufferBuilder& builder) { auto array = TRY(JsonArraySerializer<>::try_create(builder)); - TRY(JailManagement::the().for_each_in_same_jail([&array](Jail& jail) -> ErrorOr<void> { + TRY(Jail::for_each_when_process_is_not_jailed([&array](Jail const& jail) -> ErrorOr<void> { auto obj = TRY(array.add_object()); TRY(obj.add("index"sv, jail.index().value())); TRY(obj.add("name"sv, jail.name())); diff --git a/Kernel/Jail.cpp b/Kernel/Jail.cpp index faeed507f1..3b546ee32b 100644 --- a/Kernel/Jail.cpp +++ b/Kernel/Jail.cpp @@ -1,21 +1,70 @@ /* - * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il> * * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/IntrusiveList.h> +#include <AK/Singleton.h> #include <Kernel/Jail.h> +#include <Kernel/Process.h> namespace Kernel { -ErrorOr<NonnullLockRefPtr<Jail>> Jail::create(Badge<JailManagement>, NonnullOwnPtr<KString> name, JailIndex index) +static Atomic<u64> s_jail_id; +static Singleton<SpinlockProtected<Jail::List, LockRank::None>> s_all_instances {}; + +static JailIndex generate_jail_id() { - return adopt_nonnull_lock_ref_or_enomem(new (nothrow) Jail(move(name), index)); + return s_jail_id.fetch_add(1); +} + +NonnullRefPtr<ProcessList> Jail::process_list() +{ + return m_process_list; +} + +ErrorOr<NonnullLockRefPtr<Jail>> Jail::create(NonnullOwnPtr<KString> name) +{ + return s_all_instances->with([&](auto& list) -> ErrorOr<NonnullLockRefPtr<Jail>> { + auto process_list = TRY(ProcessList::create()); + auto jail = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Jail(move(name), generate_jail_id(), move(process_list)))); + list.append(jail); + return jail; + }); +} + +ErrorOr<void> Jail::for_each_when_process_is_not_jailed(Function<ErrorOr<void>(Jail const&)> callback) +{ + return Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> { + // Note: If we are in a jail, don't reveal anything about the outside world, + // not even the fact that we are in which jail... + if (my_jail) + return {}; + return s_all_instances->with([&](auto& list) -> ErrorOr<void> { + for (auto& jail : list) { + TRY(callback(jail)); + } + return {}; + }); + }); +} + +LockRefPtr<Jail> Jail::find_by_index(JailIndex index) +{ + return s_all_instances->with([&](auto& list) -> LockRefPtr<Jail> { + for (auto& jail : list) { + if (jail.index() == index) + return jail; + } + return {}; + }); } -Jail::Jail(NonnullOwnPtr<KString> name, JailIndex index) +Jail::Jail(NonnullOwnPtr<KString> name, JailIndex index, NonnullRefPtr<ProcessList> process_list) : m_name(move(name)) , m_index(index) + , m_process_list(move(process_list)) { } @@ -26,7 +75,7 @@ void Jail::detach(Badge<Process>) VERIFY(my_attach_count > 0); my_attach_count--; if (my_attach_count == 0) { - m_jail_list_node.remove(); + m_list_node.remove(); } }); } diff --git a/Kernel/Jail.h b/Kernel/Jail.h index bfbc6c833a..355c15c4ab 100644 --- a/Kernel/Jail.h +++ b/Kernel/Jail.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +9,7 @@ #include <AK/DistinctNumeric.h> #include <AK/Error.h> #include <AK/IntrusiveList.h> +#include <AK/IntrusiveListRelaxedConst.h> #include <AK/OwnPtr.h> #include <AK/RefPtr.h> #include <AK/Try.h> @@ -16,19 +17,21 @@ #include <Kernel/KString.h> #include <Kernel/Library/LockRefPtr.h> #include <Kernel/Locking/SpinlockProtected.h> -#include <Kernel/Process.h> namespace Kernel { -class JailManagement; +class ProcessList; AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, JailIndex); class Jail : public RefCounted<Jail> { - friend class JailManagement; public: - static ErrorOr<NonnullLockRefPtr<Jail>> create(Badge<JailManagement>, NonnullOwnPtr<KString>, JailIndex); + NonnullRefPtr<ProcessList> process_list(); + + static LockRefPtr<Jail> find_by_index(JailIndex); + static ErrorOr<NonnullLockRefPtr<Jail>> create(NonnullOwnPtr<KString> name); + static ErrorOr<void> for_each_when_process_is_not_jailed(Function<ErrorOr<void>(Jail const&)> callback); StringView name() const { return m_name->view(); } JailIndex index() const { return m_index; } @@ -37,12 +40,19 @@ public: SpinlockProtected<size_t, LockRank::None>& attach_count() { return m_attach_count; } private: - Jail(NonnullOwnPtr<KString>, JailIndex); + Jail(NonnullOwnPtr<KString>, JailIndex, NonnullRefPtr<ProcessList>); NonnullOwnPtr<KString> m_name; JailIndex const m_index; - IntrusiveListNode<Jail, NonnullLockRefPtr<Jail>> m_jail_list_node; + IntrusiveListNode<Jail, NonnullLockRefPtr<Jail>> m_list_node; + +public: + using List = IntrusiveListRelaxedConst<&Jail::m_list_node>; + +private: + NonnullRefPtr<ProcessList> m_process_list; + SpinlockProtected<size_t, LockRank::None> m_attach_count { 0 }; }; diff --git a/Kernel/JailManagement.cpp b/Kernel/JailManagement.cpp deleted file mode 100644 index df927ced6d..0000000000 --- a/Kernel/JailManagement.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <AK/Singleton.h> -#include <Kernel/JailManagement.h> -#include <Kernel/Process.h> -#include <Kernel/Sections.h> - -namespace Kernel { - -static Singleton<JailManagement> s_the; -static Atomic<u64> s_jail_id; - -UNMAP_AFTER_INIT JailManagement::JailManagement() = default; - -JailIndex JailManagement::generate_jail_id() -{ - return s_jail_id.fetch_add(1); -} - -JailManagement& JailManagement::the() -{ - return *s_the; -} - -LockRefPtr<Jail> JailManagement::find_jail_by_index(JailIndex index) -{ - return m_jails.with([&](auto& list) -> LockRefPtr<Jail> { - for (auto& jail : list) { - if (jail.index() == index) - return jail; - } - return {}; - }); -} - -ErrorOr<void> JailManagement::for_each_in_same_jail(Function<ErrorOr<void>(Jail&)> callback) -{ - return Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> { - // Note: If we are in a jail, don't reveal anything about the outside world, - // not even the fact that we are in which jail... - if (my_jail) - return {}; - return m_jails.with([&](auto& list) -> ErrorOr<void> { - for (auto& jail : list) { - TRY(callback(jail)); - } - return {}; - }); - }); -} - -LockRefPtr<Jail> JailManagement::find_first_jail_by_name(StringView name) -{ - return m_jails.with([&](auto& list) -> LockRefPtr<Jail> { - for (auto& jail : list) { - if (jail.name() == name) - return jail; - } - return {}; - }); -} - -ErrorOr<NonnullLockRefPtr<Jail>> JailManagement::create_jail(NonnullOwnPtr<KString> name) -{ - return m_jails.with([&](auto& list) -> ErrorOr<NonnullLockRefPtr<Jail>> { - auto jail = TRY(Jail::create({}, move(name), generate_jail_id())); - list.append(jail); - return jail; - }); -} - -} diff --git a/Kernel/JailManagement.h b/Kernel/JailManagement.h deleted file mode 100644 index 76fe91cf82..0000000000 --- a/Kernel/JailManagement.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <AK/DistinctNumeric.h> -#include <AK/Error.h> -#include <AK/IntrusiveList.h> -#include <AK/OwnPtr.h> -#include <AK/RefPtr.h> -#include <AK/Try.h> -#include <AK/Types.h> -#include <Kernel/Jail.h> -#include <Kernel/KString.h> -#include <Kernel/Library/LockRefPtr.h> -#include <Kernel/Locking/SpinlockProtected.h> - -namespace Kernel { - -class JailManagement { - -public: - JailManagement(); - static JailManagement& the(); - - LockRefPtr<Jail> find_jail_by_index(JailIndex); - LockRefPtr<Jail> find_first_jail_by_name(StringView); - - ErrorOr<NonnullLockRefPtr<Jail>> create_jail(NonnullOwnPtr<KString> name); - - ErrorOr<void> for_each_in_same_jail(Function<ErrorOr<void>(Jail&)>); - -private: - JailIndex generate_jail_id(); - - SpinlockProtected<IntrusiveList<&Jail::m_jail_list_node>, LockRank::None> m_jails {}; -}; - -} diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 504484976f..2783dce4aa 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -48,7 +48,7 @@ extern ProcessID g_init_pid; RecursiveSpinlock<LockRank::None> g_profiling_lock {}; static Atomic<pid_t> next_pid; -static Singleton<SpinlockProtected<Process::List, LockRank::None>> s_all_instances; +static Singleton<SpinlockProtected<Process::AllProcessesList, LockRank::None>> s_all_instances; READONLY_AFTER_INIT Memory::Region* g_signal_trampoline_region; static Singleton<MutexProtected<OwnPtr<KString>>> s_hostname; @@ -58,98 +58,89 @@ MutexProtected<OwnPtr<KString>>& hostname() return *s_hostname; } -SpinlockProtected<Process::List, LockRank::None>& Process::all_instances() +SpinlockProtected<Process::AllProcessesList, LockRank::None>& Process::all_instances() { return *s_all_instances; } ErrorOr<void> Process::for_each_in_same_jail(Function<ErrorOr<void>(Process&)> callback) { - ErrorOr<void> result {}; - Process::all_instances().with([&](auto const& list) { - Process::current().jail().with([&](auto const& my_jail) { - for (auto& process : list) { - if (!my_jail) { + return Process::current().m_jail_process_list.with([&](auto const& list_ptr) -> ErrorOr<void> { + ErrorOr<void> result {}; + if (list_ptr) { + list_ptr->attached_processes().with([&](auto const& list) { + for (auto& process : list) { result = callback(process); - } else { - // Note: Don't acquire the process jail spinlock twice if it's the same process - // we are currently inspecting. - if (&Process::current() == &process) { - result = callback(process); - } else { - process.jail().with([&](auto const& their_jail) { - if (their_jail.ptr() == my_jail.ptr()) - result = callback(process); - }); - } + if (result.is_error()) + break; } + }); + return result; + } + all_instances().with([&](auto const& list) { + for (auto& process : list) { + result = callback(process); if (result.is_error()) break; } }); + return result; }); - return result; } ErrorOr<void> Process::for_each_child_in_same_jail(Function<ErrorOr<void>(Process&)> callback) { ProcessID my_pid = pid(); - ErrorOr<void> result {}; - Process::all_instances().with([&](auto const& list) { - jail().with([&](auto const& my_jail) { - for (auto& process : list) { - if (!my_jail) { + return m_jail_process_list.with([&](auto const& list_ptr) -> ErrorOr<void> { + ErrorOr<void> result {}; + if (list_ptr) { + list_ptr->attached_processes().with([&](auto const& list) { + for (auto& process : list) { if (process.ppid() == my_pid || process.has_tracee_thread(pid())) result = callback(process); - } else { - // FIXME: Is it possible to have a child process being pointing to itself - // as the parent process under normal conditions? - // Note: Don't acquire the process jail spinlock twice if it's the same process - // we are currently inspecting. - if (&Process::current() == &process && (process.ppid() == my_pid || process.has_tracee_thread(pid()))) { - result = callback(process); - } else { - process.jail().with([&](auto const& their_jail) { - if ((their_jail.ptr() == my_jail.ptr()) && (process.ppid() == my_pid || process.has_tracee_thread(pid()))) - result = callback(process); - }); - } + if (result.is_error()) + break; } + }); + return result; + } + all_instances().with([&](auto const& list) { + for (auto& process : list) { + if (process.ppid() == my_pid || process.has_tracee_thread(pid())) + result = callback(process); if (result.is_error()) break; } }); + return result; }); - return result; } ErrorOr<void> Process::for_each_in_pgrp_in_same_jail(ProcessGroupID pgid, Function<ErrorOr<void>(Process&)> callback) { - ErrorOr<void> result {}; - Process::all_instances().with([&](auto const& list) { - jail().with([&](auto const& my_jail) { - for (auto& process : list) { - if (!my_jail) { + return m_jail_process_list.with([&](auto const& list_ptr) -> ErrorOr<void> { + ErrorOr<void> result {}; + if (list_ptr) { + list_ptr->attached_processes().with([&](auto const& list) { + for (auto& process : list) { if (!process.is_dead() && process.pgid() == pgid) result = callback(process); - } else { - // Note: Don't acquire the process jail spinlock twice if it's the same process - // we are currently inspecting. - if (&Process::current() == &process && !process.is_dead() && process.pgid() == pgid) { - result = callback(process); - } else { - process.jail().with([&](auto const& their_jail) { - if ((their_jail.ptr() == my_jail.ptr()) && !process.is_dead() && process.pgid() == pgid) - result = callback(process); - }); - } + if (result.is_error()) + break; } + }); + return result; + } + all_instances().with([&](auto const& list) { + for (auto& process : list) { + if (!process.is_dead() && process.pgid() == pgid) + result = callback(process); if (result.is_error()) break; } }); + return result; }); - return result; } ProcessID Process::allocate_pid() @@ -502,23 +493,21 @@ void Process::crash(int signal, Optional<RegisterState const&> regs, bool out_of LockRefPtr<Process> Process::from_pid_in_same_jail(ProcessID pid) { - return Process::current().jail().with([&](auto const& my_jail) -> LockRefPtr<Process> { - return all_instances().with([&](auto const& list) -> LockRefPtr<Process> { - if (!my_jail) { + return Process::current().m_jail_process_list.with([&](auto const& list_ptr) -> LockRefPtr<Process> { + if (list_ptr) { + return list_ptr->attached_processes().with([&](auto const& list) -> LockRefPtr<Process> { for (auto& process : list) { if (process.pid() == pid) { return process; } } - } else { - for (auto& process : list) { - if (process.pid() == pid) { - return process.jail().with([&](auto const& other_process_jail) -> LockRefPtr<Process> { - if (other_process_jail.ptr() == my_jail.ptr()) - return process; - return {}; - }); - } + return {}; + }); + } + return all_instances().with([&](auto const& list) -> LockRefPtr<Process> { + for (auto& process : list) { + if (process.pid() == pid) { + return process; } } return {}; @@ -773,6 +762,13 @@ void Process::finalize() m_fds.with_exclusive([](auto& fds) { fds.clear(); }); m_tty = nullptr; m_executable.with([](auto& executable) { executable = nullptr; }); + m_jail_process_list.with([this](auto& list_ptr) { + if (list_ptr) { + list_ptr->attached_processes().with([&](auto& list) { + list.remove(*this); + }); + } + }); m_attached_jail.with([](auto& jail) { if (jail) jail->detach({}); diff --git a/Kernel/Process.h b/Kernel/Process.h index 703cbb1dc9..a5e1e11341 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -104,6 +104,8 @@ static_assert(sizeof(GlobalFutexKey) == (sizeof(FlatPtr) * 2)); struct LoadResult; +class ProcessList; + class Process final : public ListedRefCounted<Process, LockType::Spinlock> , public LockWeakable<Process> { @@ -665,8 +667,6 @@ private: return nullptr; } - IntrusiveListNode<Process> m_list_node; - SpinlockProtected<NonnullOwnPtr<KString>, LockRank::None> m_name; SpinlockProtected<OwnPtr<Memory::AddressSpace>, LockRank::None> m_space; @@ -852,7 +852,15 @@ private: LockWeakPtr<Memory::Region> m_master_tls_region; - IntrusiveListNode<Process> m_jail_list_node; + IntrusiveListNode<Process> m_jail_process_list_node; + IntrusiveListNode<Process> m_all_processes_list_node; + +public: + using AllProcessesList = IntrusiveListRelaxedConst<&Process::m_all_processes_list_node>; + using JailProcessList = IntrusiveListRelaxedConst<&Process::m_jail_process_list_node>; + +private: + SpinlockProtected<RefPtr<ProcessList>, LockRank::None> m_jail_process_list; SpinlockProtected<RefPtr<Jail>, LockRank::Process> m_attached_jail {}; size_t m_master_tls_size { 0 }; @@ -895,8 +903,18 @@ private: u8 m_protected_values_padding[PAGE_SIZE - sizeof(ProtectedValues)]; public: - using List = IntrusiveListRelaxedConst<&Process::m_list_node>; - static SpinlockProtected<Process::List, LockRank::None>& all_instances(); + static SpinlockProtected<Process::AllProcessesList, LockRank::None>& all_instances(); +}; + +class ProcessList : public RefCounted<ProcessList> { +public: + static ErrorOr<NonnullRefPtr<ProcessList>> create(); + SpinlockProtected<Process::JailProcessList, LockRank::None>& attached_processes() { return m_attached_processes; } + SpinlockProtected<Process::JailProcessList, LockRank::None> const& attached_processes() const { return m_attached_processes; } + +private: + ProcessList() = default; + SpinlockProtected<Process::JailProcessList, LockRank::None> m_attached_processes; }; // Note: Process object should be 2 pages of 4096 bytes each. diff --git a/Kernel/ProcessList.cpp b/Kernel/ProcessList.cpp new file mode 100644 index 0000000000..aae12f7250 --- /dev/null +++ b/Kernel/ProcessList.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Process.h> + +namespace Kernel { + +ErrorOr<NonnullRefPtr<ProcessList>> ProcessList::create() +{ + return adopt_nonnull_ref_or_enomem(new (nothrow) ProcessList()); +} + +} diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 0f68783717..83e2b37a66 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -516,6 +516,7 @@ ErrorOr<void> Process::do_exec(NonnullRefPtr<OpenFileDescription> main_program_d auto old_credentials = this->credentials(); auto new_credentials = old_credentials; auto old_process_attached_jail = m_attached_jail.with([&](auto& jail) -> RefPtr<Jail> { return jail; }); + auto old_scoped_list = m_jail_process_list.with([&](auto& list) -> RefPtr<ProcessList> { return list; }); bool executable_is_setid = false; @@ -578,6 +579,11 @@ ErrorOr<void> Process::do_exec(NonnullRefPtr<OpenFileDescription> main_program_d m_attached_jail.with([&](auto& jail) { jail = old_process_attached_jail; }); + + m_jail_process_list.with([&](auto& list) { + list = old_scoped_list; + }); + m_environment = move(environment); TRY(m_unveil_data.with([&](auto& unveil_data) -> ErrorOr<void> { diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index 148926e3e9..4c9924bb55 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -70,6 +70,26 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs) return {}; })); + ArmedScopeGuard remove_from_jail_process_list = [&]() { + m_jail_process_list.with([&](auto& list_ptr) { + if (list_ptr) { + list_ptr->attached_processes().with([&](auto& list) { + list.remove(*child); + }); + } + }); + }; + m_jail_process_list.with([&](auto& list_ptr) { + if (list_ptr) { + child->m_jail_process_list.with([&](auto& child_list_ptr) { + child_list_ptr = list_ptr; + }); + list_ptr->attached_processes().with([&](auto& list) { + list.append(child); + }); + } + }); + TRY(child->m_fds.with_exclusive([&](auto& child_fds) { return m_fds.with_exclusive([&](auto& parent_fds) { return child_fds.try_clone(parent_fds); @@ -150,6 +170,7 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs) })); thread_finalizer_guard.disarm(); + remove_from_jail_process_list.disarm(); Process::register_new(*child); diff --git a/Kernel/Syscalls/jail.cpp b/Kernel/Syscalls/jail.cpp index 4d84935fb6..5a36bcbce1 100644 --- a/Kernel/Syscalls/jail.cpp +++ b/Kernel/Syscalls/jail.cpp @@ -7,7 +7,6 @@ #include <AK/Userspace.h> #include <Kernel/API/Ioctl.h> #include <Kernel/Jail.h> -#include <Kernel/JailManagement.h> #include <Kernel/Process.h> #include <Kernel/StdLib.h> @@ -31,7 +30,7 @@ ErrorOr<FlatPtr> Process::sys$jail_create(Userspace<Syscall::SC_jail_create_para // any info leak about the "outside world" jail metadata. if (my_jail) return Error::from_errno(EPERM); - auto jail = TRY(JailManagement::the().create_jail(move(jail_name))); + auto jail = TRY(Jail::create(move(jail_name))); return jail->index().value(); })); // Note: We do the copy_to_user outside of the m_attached_jail Spinlock locked scope because @@ -64,13 +63,21 @@ ErrorOr<FlatPtr> Process::sys$jail_attach(Userspace<Syscall::SC_jail_attach_para // in the system, just return EPERM before doing anything else. if (my_jail) return EPERM; - auto jail = JailManagement::the().find_jail_by_index(static_cast<JailIndex>(params.index)); + auto jail = Jail::find_by_index(static_cast<JailIndex>(params.index)); if (!jail) return EINVAL; my_jail = *jail; my_jail->attach_count().with([&](auto& attach_count) { attach_count++; }); + m_jail_process_list.with([&](auto& list_ptr) { + list_ptr = my_jail->process_list(); + if (list_ptr) { + list_ptr->attached_processes().with([&](auto& list) { + list.append(*this); + }); + } + }); return 0; }); } |