summaryrefslogtreecommitdiff
path: root/Kernel/JailManagement.cpp
blob: 3735c92f7375eb9e4d105c26611da0466257797a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
 * 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& 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;
    });
}

}