1
2
3
4
5
6
7
8
9#include <asm/current.h>
10#include <linux/cred.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/lsm_hooks.h>
14#include <linux/rcupdate.h>
15#include <linux/sched.h>
16
17#include "common.h"
18#include "cred.h"
19#include "ptrace.h"
20#include "ruleset.h"
21#include "setup.h"
22
23
24
25
26
27
28
29
30
31
32static bool domain_scope_le(const struct landlock_ruleset *const parent,
33 const struct landlock_ruleset *const child)
34{
35 const struct landlock_hierarchy *walker;
36
37 if (!parent)
38 return true;
39 if (!child)
40 return false;
41 for (walker = child->hierarchy; walker; walker = walker->parent) {
42 if (walker == parent->hierarchy)
43
44 return true;
45 }
46
47 return false;
48}
49
50static bool task_is_scoped(const struct task_struct *const parent,
51 const struct task_struct *const child)
52{
53 bool is_scoped;
54 const struct landlock_ruleset *dom_parent, *dom_child;
55
56 rcu_read_lock();
57 dom_parent = landlock_get_task_domain(parent);
58 dom_child = landlock_get_task_domain(child);
59 is_scoped = domain_scope_le(dom_parent, dom_child);
60 rcu_read_unlock();
61 return is_scoped;
62}
63
64static int task_ptrace(const struct task_struct *const parent,
65 const struct task_struct *const child)
66{
67
68 if (!landlocked(parent))
69 return 0;
70 if (task_is_scoped(parent, child))
71 return 0;
72 return -EPERM;
73}
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88static int hook_ptrace_access_check(struct task_struct *const child,
89 const unsigned int mode)
90{
91 return task_ptrace(current, child);
92}
93
94
95
96
97
98
99
100
101
102
103
104
105
106static int hook_ptrace_traceme(struct task_struct *const parent)
107{
108 return task_ptrace(parent, current);
109}
110
111static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
112 LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check),
113 LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme),
114};
115
116__init void landlock_add_ptrace_hooks(void)
117{
118 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
119 LANDLOCK_NAME);
120}
121