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 * Copyright © 2026 Cloudflare, Inc. 9 */ 10 11 #ifndef _SECURITY_LANDLOCK_DOMAIN_H 12 #define _SECURITY_LANDLOCK_DOMAIN_H 13 14 #include <linux/cleanup.h> 15 #include <linux/limits.h> 16 #include <linux/mm.h> 17 #include <linux/path.h> 18 #include <linux/pid.h> 19 #include <linux/refcount.h> 20 #include <linux/sched.h> 21 #include <linux/slab.h> 22 #include <linux/workqueue.h> 23 24 #include "access.h" 25 #include "log.h" 26 #include "ruleset.h" 27 28 enum landlock_log_status { 29 /* 30 * Hierarchy whose creation event has not been emitted, so it is not yet 31 * observable from user space. A hierarchy is born in this state (the 32 * zero value, so a partially initialized hierarchy defaults to "not 33 * observable") and leaves it when landlock_restrict_self() emits its 34 * creation event, right after the merge and before the thread-sync 35 * wait. No trace free_domain event (and no audit deallocation record) 36 * fires while a hierarchy is in this state, so a hierarchy that never 37 * became observable (e.g. its initialization failed) is freed silently. 38 * A domain aborted by a thread-sync failure already emitted its 39 * creation event, so it is no longer UNCOMMITTED and does fire 40 * free_domain. 41 */ 42 LANDLOCK_LOG_UNCOMMITTED = 0, 43 LANDLOCK_LOG_PENDING, 44 LANDLOCK_LOG_RECORDED, 45 LANDLOCK_LOG_DISABLED, 46 }; 47 48 /** 49 * struct landlock_details - Domain's creation information 50 * 51 * Rarely accessed, mainly when logging the first domain's denial. 52 * 53 * The contained pointers are initialized at the domain creation time and never 54 * changed again. 55 */ 56 struct landlock_details { 57 /** 58 * @pid: PID of the task that initially restricted itself. It still 59 * identifies the same task. Keeping a reference to this PID ensures that 60 * it will not be recycled. 61 */ 62 struct pid *pid; 63 /** 64 * @uid: UID of the task that initially restricted itself, at creation time. 65 */ 66 uid_t uid; 67 /** 68 * @comm: Command line of the task that initially restricted itself, at 69 * creation time. Always NULL terminated. 70 */ 71 char comm[TASK_COMM_LEN]; 72 /** 73 * @exe_path: Executable path of the task that initially restricted 74 * itself, at creation time. Always NULL terminated, and never greater 75 * than LANDLOCK_PATH_MAX_SIZE. 76 */ 77 char exe_path[]; 78 }; 79 80 /* Adds 11 extra characters for the potential " (deleted)" suffix. */ 81 #define LANDLOCK_PATH_MAX_SIZE (PATH_MAX + 11) 82 83 /* Makes sure the greatest landlock_details can be allocated. */ 84 static_assert(struct_size_t(struct landlock_details, exe_path, 85 LANDLOCK_PATH_MAX_SIZE) <= KMALLOC_MAX_SIZE); 86 87 /** 88 * struct landlock_hierarchy - Node in a domain hierarchy 89 */ 90 struct landlock_hierarchy { 91 /** 92 * @parent: Pointer to the parent node, or NULL if it is a root 93 * Landlock domain. 94 */ 95 struct landlock_hierarchy *parent; 96 /** 97 * @usage: Number of potential children domains plus their parent 98 * domain. 99 */ 100 refcount_t usage; 101 102 #ifdef CONFIG_SECURITY_LANDLOCK_LOG 103 /** 104 * @log_status: Whether this domain should be logged or not. Because 105 * concurrent log entries may be created at the same time, it is still 106 * possible to have several domain records of the same domain. 107 */ 108 enum landlock_log_status log_status; 109 /** 110 * @num_denials: Number of access requests denied by this domain. 111 * Masked (i.e. never logged) denials are still counted. 112 */ 113 atomic64_t num_denials; 114 /** 115 * @id: Landlock domain ID, set once at domain creation time. 116 */ 117 u64 id; 118 /** 119 * @details: Information about the related domain. 120 */ 121 const struct landlock_details *details; 122 /** 123 * @log_same_exec: Set if the domain is *not* configured with 124 * %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF. Set to true by default. 125 */ 126 u32 log_same_exec : 1, 127 /** 128 * @log_new_exec: Set if the domain is configured with 129 * %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON. Set to false by default. 130 */ 131 log_new_exec : 1; 132 /** 133 * @quiet_masks: Bitmasks of access that should be quieted (i.e. not 134 * logged) if the related object is marked as quiet. 135 */ 136 struct access_masks quiet_masks; 137 #endif /* CONFIG_SECURITY_LANDLOCK_LOG */ 138 }; 139 140 #ifdef CONFIG_SECURITY_LANDLOCK_LOG 141 142 deny_masks_t 143 landlock_get_deny_masks(const access_mask_t all_existing_optional_access, 144 const access_mask_t optional_access, 145 const struct layer_masks *const masks); 146 147 optional_access_t landlock_get_quiet_optional_accesses( 148 const access_mask_t all_existing_optional_access, 149 const deny_masks_t deny_masks, const struct layer_masks *const masks); 150 151 int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy); 152 153 static inline void 154 landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy) 155 { 156 if (!hierarchy || !hierarchy->details) 157 return; 158 159 put_pid(hierarchy->details->pid); 160 kfree(hierarchy->details); 161 } 162 163 #else /* CONFIG_SECURITY_LANDLOCK_LOG */ 164 165 static inline int 166 landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy) 167 { 168 return 0; 169 } 170 171 static inline void 172 landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy) 173 { 174 } 175 176 #endif /* CONFIG_SECURITY_LANDLOCK_LOG */ 177 178 static inline void 179 landlock_get_hierarchy(struct landlock_hierarchy *const hierarchy) 180 { 181 if (hierarchy) 182 refcount_inc(&hierarchy->usage); 183 } 184 185 static inline void landlock_put_hierarchy(struct landlock_hierarchy *hierarchy) 186 { 187 while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) { 188 const struct landlock_hierarchy *const freeme = hierarchy; 189 190 landlock_log_free_domain(hierarchy); 191 landlock_free_hierarchy_details(hierarchy); 192 hierarchy = hierarchy->parent; 193 kfree(freeme); 194 } 195 } 196 197 /** 198 * struct landlock_domain - Immutable Landlock domain 199 * 200 * A domain is created from a ruleset by landlock_merge_ruleset() and enforced 201 * on a task. Once created, its rules and access masks are immutable. Unlike 202 * &struct landlock_ruleset, a domain has no lock field. 203 */ 204 struct landlock_domain { 205 /** 206 * @rules: Red-black tree storage for rules. 207 */ 208 struct landlock_rules rules; 209 /** 210 * @hierarchy: Enables hierarchy identification even when a parent 211 * domain vanishes. This is needed for the ptrace and scope 212 * restrictions. 213 */ 214 struct landlock_hierarchy *hierarchy; 215 union { 216 /** 217 * @work_free: Enables to free a domain within a lockless 218 * section. This is only used by landlock_put_domain_deferred() 219 * when @usage reaches zero. The fields @usage, @num_layers and 220 * @handled_masks are then unused. 221 */ 222 struct work_struct work_free; 223 struct { 224 /** 225 * @usage: Number of credentials referencing this 226 * domain. 227 */ 228 refcount_t usage; 229 /** 230 * @num_layers: Number of layers that are used in this 231 * domain. This enables to check that all the layers 232 * allow an access request. 233 */ 234 u32 num_layers; 235 /** 236 * @handled_masks: Contains the subset of filesystem and 237 * network actions that are restricted by a domain. A 238 * domain saves all layers of merged rulesets in a stack 239 * (FAM), starting from the first layer to the last one. 240 * These layers are used when merging rulesets, for user 241 * space backward compatibility (i.e. future-proof), and 242 * to properly handle merged rulesets without 243 * overlapping access rights. These layers are set once 244 * and never changed for the lifetime of the domain. 245 */ 246 struct access_masks handled_masks[]; 247 }; 248 }; 249 }; 250 251 static inline access_mask_t 252 landlock_get_fs_access_mask(const struct landlock_domain *const domain, 253 const u16 layer_level) 254 { 255 /* Handles all initially denied by default access rights. */ 256 return domain->handled_masks[layer_level].fs | 257 _LANDLOCK_ACCESS_FS_INITIALLY_DENIED; 258 } 259 260 static inline access_mask_t 261 landlock_get_net_access_mask(const struct landlock_domain *const domain, 262 const u16 layer_level) 263 { 264 return domain->handled_masks[layer_level].net; 265 } 266 267 static inline access_mask_t 268 landlock_get_scope_mask(const struct landlock_domain *const domain, 269 const u16 layer_level) 270 { 271 return domain->handled_masks[layer_level].scope; 272 } 273 274 /** 275 * landlock_union_access_masks - Return all access rights handled in the 276 * domain 277 * 278 * @domain: Landlock domain 279 * 280 * Return: An access_masks result of the OR of all the domain's access masks. 281 */ 282 static inline struct access_masks 283 landlock_union_access_masks(const struct landlock_domain *const domain) 284 { 285 union access_masks_all matches = {}; 286 size_t layer_level; 287 288 for (layer_level = 0; layer_level < domain->num_layers; layer_level++) { 289 union access_masks_all layer = { 290 .masks = domain->handled_masks[layer_level], 291 }; 292 293 matches.all |= layer.all; 294 } 295 296 return matches.masks; 297 } 298 299 void landlock_put_domain(struct landlock_domain *const domain); 300 void landlock_put_domain_deferred(struct landlock_domain *const domain); 301 302 DEFINE_FREE(landlock_put_domain, struct landlock_domain *, 303 if (!IS_ERR_OR_NULL(_T)) landlock_put_domain(_T)) 304 305 struct landlock_domain * 306 landlock_merge_ruleset(struct landlock_domain *const parent, 307 struct landlock_ruleset *const ruleset); 308 309 bool landlock_unmask_layers(const struct landlock_domain *const domain, 310 const struct landlock_id id, 311 struct layer_masks *masks, 312 const struct landlock_rule **matched_rule); 313 314 access_mask_t 315 landlock_init_layer_masks(const struct landlock_domain *const domain, 316 const access_mask_t access_request, 317 struct layer_masks *masks, 318 const enum landlock_key_type key_type); 319 320 static inline void landlock_get_domain(struct landlock_domain *const domain) 321 { 322 if (domain) 323 refcount_inc(&domain->usage); 324 } 325 326 #endif /* _SECURITY_LANDLOCK_DOMAIN_H */ 327