> } > + if (is_empty) > + return true; > } > - return layer_mask; > + return false; > } > > static int check_access_path(const struct landlock_ruleset *const domain, > const struct path *const path, > const access_mask_t access_request) > { > - bool allowed = false; > + layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; > + bool allowed = false, has_access = false; > struct path walker_path; > - layer_mask_t layer_mask; > size_t i; > > if (!access_request) > @@ -262,13 +283,20 @@ static int check_access_path(const struct landlock_ruleset *const domain, > return -EACCES; > > /* Saves all layers handling a subset of requested accesses. */ > - layer_mask = 0; > for (i = 0; i < domain->num_layers; i++) { > - if (domain->fs_access_masks[i] & access_request) > - layer_mask |= BIT_ULL(i); > + const unsigned long access_req = access_request; > + unsigned long access_bit; > + > + for_each_set_bit(access_bit, &access_req, > + ARRAY_SIZE(layer_masks)) { > + if (domain->fs_access_masks[i] & BIT_ULL(access_bit)) { > + layer_masks[access_bit] |= BIT_ULL(i); > + has_access = true; > + } > + } > } > /* An access request not handled by the domain is allowed. */ > - if (layer_mask == 0) > + if (!has_access) > return 0; > > walker_path = *path; > @@ -280,14 +308,11 @@ static int check_access_path(const struct landlock_ruleset *const domain, > while (true) { > struct dentry *parent_dentry; > > - layer_mask = unmask_layers(find_rule(domain, > - walker_path.dentry), access_request, > - layer_mask); > - if (layer_mask == 0) { > + allowed = unmask_layers(find_rule(domain, walker_path.dentry), > + access_request, &layer_masks); > + if (allowed) > /* Stops when a rule from each layer grants access. */ > - allowed = true; > break; > - } > > jump_up: > if (walker_path.dentry == walker_path.mnt->mnt_root) { -- paul-moore.com