Serenity Operating System
at master 83 lines 2.2 kB view raw
1/* 2 * Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/IntrusiveList.h> 8#include <AK/Singleton.h> 9#include <Kernel/Jail.h> 10#include <Kernel/Process.h> 11 12namespace Kernel { 13 14static Atomic<u64> s_jail_id; 15static Singleton<SpinlockProtected<Jail::List, LockRank::None>> s_all_instances {}; 16 17static JailIndex generate_jail_id() 18{ 19 return s_jail_id.fetch_add(1); 20} 21 22NonnullRefPtr<ProcessList> Jail::process_list() 23{ 24 return m_process_list; 25} 26 27ErrorOr<NonnullLockRefPtr<Jail>> Jail::create(NonnullOwnPtr<KString> name) 28{ 29 return s_all_instances->with([&](auto& list) -> ErrorOr<NonnullLockRefPtr<Jail>> { 30 auto process_list = TRY(ProcessList::create()); 31 auto jail = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Jail(move(name), generate_jail_id(), move(process_list)))); 32 list.append(jail); 33 return jail; 34 }); 35} 36 37ErrorOr<void> Jail::for_each_when_process_is_not_jailed(Function<ErrorOr<void>(Jail const&)> callback) 38{ 39 return Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> { 40 // Note: If we are in a jail, don't reveal anything about the outside world, 41 // not even the fact that we are in which jail... 42 if (my_jail) 43 return {}; 44 return s_all_instances->with([&](auto& list) -> ErrorOr<void> { 45 for (auto& jail : list) { 46 TRY(callback(jail)); 47 } 48 return {}; 49 }); 50 }); 51} 52 53LockRefPtr<Jail> Jail::find_by_index(JailIndex index) 54{ 55 return s_all_instances->with([&](auto& list) -> LockRefPtr<Jail> { 56 for (auto& jail : list) { 57 if (jail.index() == index) 58 return jail; 59 } 60 return {}; 61 }); 62} 63 64Jail::Jail(NonnullOwnPtr<KString> name, JailIndex index, NonnullRefPtr<ProcessList> process_list) 65 : m_name(move(name)) 66 , m_index(index) 67 , m_process_list(move(process_list)) 68{ 69} 70 71void Jail::detach(Badge<Process>) 72{ 73 VERIFY(ref_count() > 0); 74 m_attach_count.with([&](auto& my_attach_count) { 75 VERIFY(my_attach_count > 0); 76 my_attach_count--; 77 if (my_attach_count == 0) { 78 m_list_node.remove(); 79 } 80 }); 81} 82 83}