xref: /linux/security/landlock/domain.h (revision 1260ed77798502de9c98020040d2995008de10cc)
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, sets 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 layer_mask_t (*const layer_masks)[],
126 			size_t layer_masks_size);
127 
128 int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy);
129 
130 static inline void
131 landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)
132 {
133 	if (WARN_ON_ONCE(!hierarchy || !hierarchy->details))
134 		return;
135 
136 	put_pid(hierarchy->details->pid);
137 	kfree(hierarchy->details);
138 }
139 
140 #else /* CONFIG_AUDIT */
141 
142 static inline int
143 landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy)
144 {
145 	return 0;
146 }
147 
148 static inline void
149 landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)
150 {
151 }
152 
153 #endif /* CONFIG_AUDIT */
154 
155 static inline void
156 landlock_get_hierarchy(struct landlock_hierarchy *const hierarchy)
157 {
158 	if (hierarchy)
159 		refcount_inc(&hierarchy->usage);
160 }
161 
162 static inline void landlock_put_hierarchy(struct landlock_hierarchy *hierarchy)
163 {
164 	while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) {
165 		const struct landlock_hierarchy *const freeme = hierarchy;
166 
167 		landlock_log_drop_domain(hierarchy);
168 		landlock_free_hierarchy_details(hierarchy);
169 		hierarchy = hierarchy->parent;
170 		kfree(freeme);
171 	}
172 }
173 
174 #endif /* _SECURITY_LANDLOCK_DOMAIN_H */
175