1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Landlock - Domain management
4 *
5 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
6 * Copyright © 2018-2020 ANSSI
7 * Copyright © 2024-2025 Microsoft Corporation
8 */
9
10 #ifndef _SECURITY_LANDLOCK_DOMAIN_H
11 #define _SECURITY_LANDLOCK_DOMAIN_H
12
13 #include <linux/limits.h>
14 #include <linux/mm.h>
15 #include <linux/path.h>
16 #include <linux/pid.h>
17 #include <linux/refcount.h>
18 #include <linux/sched.h>
19 #include <linux/slab.h>
20
21 #include "access.h"
22 #include "audit.h"
23
24 enum landlock_log_status {
25 LANDLOCK_LOG_PENDING = 0,
26 LANDLOCK_LOG_RECORDED,
27 LANDLOCK_LOG_DISABLED,
28 };
29
30 /**
31 * struct landlock_details - Domain's creation information
32 *
33 * Rarely accessed, mainly when logging the first domain's denial.
34 *
35 * The contained pointers are initialized at the domain creation time and never
36 * changed again. Contrary to most other Landlock object types, this one is
37 * not allocated with GFP_KERNEL_ACCOUNT because its size may not be under the
38 * caller's control (e.g. unknown exe_path) and the data is not explicitly
39 * requested nor used by tasks.
40 */
41 struct landlock_details {
42 /**
43 * @pid: PID of the task that initially restricted itself. It still
44 * identifies the same task. Keeping a reference to this PID ensures that
45 * it will not be recycled.
46 */
47 struct pid *pid;
48 /**
49 * @uid: UID of the task that initially restricted itself, at creation time.
50 */
51 uid_t uid;
52 /**
53 * @comm: Command line of the task that initially restricted itself, at
54 * creation time. Always NULL terminated.
55 */
56 char comm[TASK_COMM_LEN];
57 /**
58 * @exe_path: Executable path of the task that initially restricted
59 * itself, at creation time. Always NULL terminated, and never greater
60 * than LANDLOCK_PATH_MAX_SIZE.
61 */
62 char exe_path[];
63 };
64
65 /* Adds 11 extra characters for the potential " (deleted)" suffix. */
66 #define LANDLOCK_PATH_MAX_SIZE (PATH_MAX + 11)
67
68 /* Makes sure the greatest landlock_details can be allocated. */
69 static_assert(struct_size_t(struct landlock_details, exe_path,
70 LANDLOCK_PATH_MAX_SIZE) <= KMALLOC_MAX_SIZE);
71
72 /**
73 * struct landlock_hierarchy - Node in a domain hierarchy
74 */
75 struct landlock_hierarchy {
76 /**
77 * @parent: Pointer to the parent node, or NULL if it is a root
78 * Landlock domain.
79 */
80 struct landlock_hierarchy *parent;
81 /**
82 * @usage: Number of potential children domains plus their parent
83 * domain.
84 */
85 refcount_t usage;
86
87 #ifdef CONFIG_AUDIT
88 /**
89 * @log_status: Whether this domain should be logged or not. Because
90 * concurrent log entries may be created at the same time, it is still
91 * possible to have several domain records of the same domain.
92 */
93 enum landlock_log_status log_status;
94 /**
95 * @num_denials: Number of access requests denied by this domain.
96 * Masked (i.e. never logged) denials are still counted.
97 */
98 atomic64_t num_denials;
99 /**
100 * @id: Landlock domain ID, set once at domain creation time.
101 */
102 u64 id;
103 /**
104 * @details: Information about the related domain.
105 */
106 const struct landlock_details *details;
107 /**
108 * @log_same_exec: Set if the domain is *not* configured with
109 * %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF. Set to true by default.
110 */
111 u32 log_same_exec : 1,
112 /**
113 * @log_new_exec: Set if the domain is configured with
114 * %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON. Set to false by default.
115 */
116 log_new_exec : 1;
117 #endif /* CONFIG_AUDIT */
118 };
119
120 #ifdef CONFIG_AUDIT
121
122 deny_masks_t
123 landlock_get_deny_masks(const access_mask_t all_existing_optional_access,
124 const access_mask_t optional_access,
125 const struct layer_access_masks *const masks);
126
127 int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy);
128
129 static inline void
landlock_free_hierarchy_details(struct landlock_hierarchy * const hierarchy)130 landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)
131 {
132 if (!hierarchy || !hierarchy->details)
133 return;
134
135 put_pid(hierarchy->details->pid);
136 kfree(hierarchy->details);
137 }
138
139 #else /* CONFIG_AUDIT */
140
141 static inline int
landlock_init_hierarchy_log(struct landlock_hierarchy * const hierarchy)142 landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy)
143 {
144 return 0;
145 }
146
147 static inline void
landlock_free_hierarchy_details(struct landlock_hierarchy * const hierarchy)148 landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)
149 {
150 }
151
152 #endif /* CONFIG_AUDIT */
153
154 static inline void
landlock_get_hierarchy(struct landlock_hierarchy * const hierarchy)155 landlock_get_hierarchy(struct landlock_hierarchy *const hierarchy)
156 {
157 if (hierarchy)
158 refcount_inc(&hierarchy->usage);
159 }
160
landlock_put_hierarchy(struct landlock_hierarchy * hierarchy)161 static inline void landlock_put_hierarchy(struct landlock_hierarchy *hierarchy)
162 {
163 while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) {
164 const struct landlock_hierarchy *const freeme = hierarchy;
165
166 landlock_log_drop_domain(hierarchy);
167 landlock_free_hierarchy_details(hierarchy);
168 hierarchy = hierarchy->parent;
169 kfree(freeme);
170 }
171 }
172
173 #endif /* _SECURITY_LANDLOCK_DOMAIN_H */
174