2022-11-02 20:26:02 +00:00
|
|
|
/*
|
2023-01-12 20:06:51 +00:00
|
|
|
* Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il>
|
2022-11-02 20:26:02 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
2023-01-12 20:06:51 +00:00
|
|
|
#include <AK/IntrusiveList.h>
|
|
|
|
#include <AK/Singleton.h>
|
2023-01-12 20:47:09 +00:00
|
|
|
#include <Kernel/API/Jail.h>
|
2023-02-24 17:34:21 +00:00
|
|
|
#include <Kernel/Security/Jail.h>
|
2023-02-24 17:45:37 +00:00
|
|
|
#include <Kernel/Tasks/Process.h>
|
2022-11-02 20:26:02 +00:00
|
|
|
|
|
|
|
namespace Kernel {
|
|
|
|
|
2023-01-12 20:06:51 +00:00
|
|
|
static Atomic<u64> s_jail_id;
|
|
|
|
static Singleton<SpinlockProtected<Jail::List, LockRank::None>> s_all_instances {};
|
|
|
|
|
|
|
|
static JailIndex generate_jail_id()
|
2022-11-02 20:26:02 +00:00
|
|
|
{
|
2023-01-12 20:06:51 +00:00
|
|
|
return s_jail_id.fetch_add(1);
|
|
|
|
}
|
|
|
|
|
2023-01-12 20:47:09 +00:00
|
|
|
RefPtr<ProcessList> Jail::process_list()
|
2023-01-12 20:06:51 +00:00
|
|
|
{
|
|
|
|
return m_process_list;
|
|
|
|
}
|
|
|
|
|
2023-01-12 20:47:09 +00:00
|
|
|
ErrorOr<NonnullRefPtr<Jail>> Jail::create(NonnullOwnPtr<KString> name, unsigned flags)
|
2023-01-12 20:06:51 +00:00
|
|
|
{
|
2023-01-12 20:47:09 +00:00
|
|
|
RefPtr<ProcessList> jail_process_list;
|
|
|
|
if (flags & static_cast<unsigned>(JailIsolationFlags::PIDIsolation))
|
|
|
|
jail_process_list = TRY(ProcessList::create());
|
|
|
|
|
2023-04-10 21:24:47 +00:00
|
|
|
return s_all_instances->with([&](auto& list) -> ErrorOr<NonnullRefPtr<Jail>> {
|
2023-01-12 20:47:09 +00:00
|
|
|
auto jail = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Jail(move(name), generate_jail_id(), jail_process_list)));
|
2023-01-12 20:06:51 +00:00
|
|
|
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 {};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-04-10 21:24:47 +00:00
|
|
|
RefPtr<Jail> Jail::find_by_index(JailIndex index)
|
2023-01-12 20:06:51 +00:00
|
|
|
{
|
2023-04-10 21:24:47 +00:00
|
|
|
return s_all_instances->with([&](auto& list) -> RefPtr<Jail> {
|
2023-01-12 20:06:51 +00:00
|
|
|
for (auto& jail : list) {
|
|
|
|
if (jail.index() == index)
|
|
|
|
return jail;
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
});
|
2022-11-02 20:26:02 +00:00
|
|
|
}
|
|
|
|
|
2023-01-12 20:47:09 +00:00
|
|
|
Jail::Jail(NonnullOwnPtr<KString> name, JailIndex index, RefPtr<ProcessList> process_list)
|
2022-11-02 20:26:02 +00:00
|
|
|
: m_name(move(name))
|
|
|
|
, m_index(index)
|
2023-01-12 20:47:09 +00:00
|
|
|
, m_process_list(process_list)
|
2022-11-02 20:26:02 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Jail::detach(Badge<Process>)
|
|
|
|
{
|
|
|
|
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) {
|
2023-01-12 20:06:51 +00:00
|
|
|
m_list_node.remove();
|
2022-11-02 20:26:02 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|