/* * Copyright (c) 2022-2023, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include namespace Kernel { static Atomic s_jail_id; static Singleton> s_all_instances {}; static JailIndex generate_jail_id() { return s_jail_id.fetch_add(1); } RefPtr Jail::process_list() { return m_process_list; } ErrorOr> Jail::create(NonnullOwnPtr name, unsigned flags) { RefPtr jail_process_list; if (flags & static_cast(JailIsolationFlags::PIDIsolation)) jail_process_list = TRY(ProcessList::create()); return s_all_instances->with([&](auto& list) -> ErrorOr> { auto jail = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Jail(move(name), generate_jail_id(), jail_process_list))); list.append(jail); return jail; }); } ErrorOr Jail::for_each_when_process_is_not_jailed(Function(Jail const&)> callback) { return Process::current().jail().with([&](auto const& my_jail) -> ErrorOr { // 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 { for (auto& jail : list) { TRY(callback(jail)); } return {}; }); }); } RefPtr Jail::find_by_index(JailIndex index) { return s_all_instances->with([&](auto& list) -> RefPtr { for (auto& jail : list) { if (jail.index() == index) return jail; } return {}; }); } Jail::Jail(NonnullOwnPtr name, JailIndex index, RefPtr process_list) : m_name(move(name)) , m_index(index) , m_process_list(process_list) { } void Jail::detach(Badge) { VERIFY(ref_count() > 0); m_attach_count.with([&](auto& my_attach_count) { VERIFY(my_attach_count > 0); my_attach_count--; if (my_attach_count == 0) { m_list_node.remove(); } }); } }