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