Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

landlock: Create find_rule() from unmask_layers()

This refactoring will be useful in a following commit.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20220506161102.525323-4-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>

+28 -13
+28 -13
security/landlock/fs.c
··· 183 183 184 184 /* Access-control management */ 185 185 186 - static inline layer_mask_t 187 - unmask_layers(const struct landlock_ruleset *const domain, 188 - const struct path *const path, const access_mask_t access_request, 189 - layer_mask_t layer_mask) 186 + /* 187 + * The lifetime of the returned rule is tied to @domain. 188 + * 189 + * Returns NULL if no rule is found or if @dentry is negative. 190 + */ 191 + static inline const struct landlock_rule * 192 + find_rule(const struct landlock_ruleset *const domain, 193 + const struct dentry *const dentry) 190 194 { 191 195 const struct landlock_rule *rule; 192 196 const struct inode *inode; 193 - size_t i; 194 197 195 - if (d_is_negative(path->dentry)) 196 - /* Ignore nonexistent leafs. */ 197 - return layer_mask; 198 - inode = d_backing_inode(path->dentry); 198 + /* Ignores nonexistent leafs. */ 199 + if (d_is_negative(dentry)) 200 + return NULL; 201 + 202 + inode = d_backing_inode(dentry); 199 203 rcu_read_lock(); 200 204 rule = landlock_find_rule( 201 205 domain, rcu_dereference(landlock_inode(inode)->object)); 202 206 rcu_read_unlock(); 207 + return rule; 208 + } 209 + 210 + static inline layer_mask_t unmask_layers(const struct landlock_rule *const rule, 211 + const access_mask_t access_request, 212 + layer_mask_t layer_mask) 213 + { 214 + size_t layer_level; 215 + 203 216 if (!rule) 204 217 return layer_mask; 205 218 ··· 223 210 * the remaining layers for each inode, from the first added layer to 224 211 * the last one. 225 212 */ 226 - for (i = 0; i < rule->num_layers; i++) { 227 - const struct landlock_layer *const layer = &rule->layers[i]; 213 + for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { 214 + const struct landlock_layer *const layer = 215 + &rule->layers[layer_level]; 228 216 const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); 229 217 230 218 /* Checks that the layer grants access to the full request. */ ··· 283 269 while (true) { 284 270 struct dentry *parent_dentry; 285 271 286 - layer_mask = unmask_layers(domain, &walker_path, access_request, 287 - layer_mask); 272 + layer_mask = 273 + unmask_layers(find_rule(domain, walker_path.dentry), 274 + access_request, layer_mask); 288 275 if (layer_mask == 0) { 289 276 /* Stops when a rule from each layer grants access. */ 290 277 allowed = true;