diff options
author | Mickaël Salaün <mic@digikod.net> | 2022-05-06 18:10:53 +0200 |
---|---|---|
committer | Mickaël Salaün <mic@digikod.net> | 2022-05-23 13:27:56 +0200 |
commit | 2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4 (patch) | |
tree | f80721e75372ccaeeaad00542eb18b2d45dc43dd /security/landlock | |
parent | 75c542d6c6cc48720376862d5496d51509160dfd (diff) | |
download | lwn-2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4.tar.gz lwn-2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4.zip |
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>
Diffstat (limited to 'security/landlock')
-rw-r--r-- | security/landlock/fs.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/security/landlock/fs.c b/security/landlock/fs.c index f48c0a3b1e75..20953bff8fd5 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -183,23 +183,36 @@ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, /* Access-control management */ -static inline layer_mask_t -unmask_layers(const struct landlock_ruleset *const domain, - const struct path *const path, const access_mask_t access_request, - layer_mask_t layer_mask) +/* + * The lifetime of the returned rule is tied to @domain. + * + * Returns NULL if no rule is found or if @dentry is negative. + */ +static inline const struct landlock_rule * +find_rule(const struct landlock_ruleset *const domain, + const struct dentry *const dentry) { const struct landlock_rule *rule; const struct inode *inode; - size_t i; - if (d_is_negative(path->dentry)) - /* Ignore nonexistent leafs. */ - return layer_mask; - inode = d_backing_inode(path->dentry); + /* Ignores nonexistent leafs. */ + if (d_is_negative(dentry)) + return NULL; + + inode = d_backing_inode(dentry); rcu_read_lock(); rule = landlock_find_rule( domain, rcu_dereference(landlock_inode(inode)->object)); rcu_read_unlock(); + return rule; +} + +static inline layer_mask_t unmask_layers(const struct landlock_rule *const rule, + const access_mask_t access_request, + layer_mask_t layer_mask) +{ + size_t layer_level; + if (!rule) return layer_mask; @@ -210,8 +223,9 @@ unmask_layers(const struct landlock_ruleset *const domain, * the remaining layers for each inode, from the first added layer to * the last one. */ - for (i = 0; i < rule->num_layers; i++) { - const struct landlock_layer *const layer = &rule->layers[i]; + for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { + const struct landlock_layer *const layer = + &rule->layers[layer_level]; const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); /* Checks that the layer grants access to the full request. */ @@ -269,8 +283,9 @@ static int check_access_path(const struct landlock_ruleset *const domain, while (true) { struct dentry *parent_dentry; - layer_mask = unmask_layers(domain, &walker_path, access_request, - layer_mask); + layer_mask = + unmask_layers(find_rule(domain, walker_path.dentry), + access_request, layer_mask); if (layer_mask == 0) { /* Stops when a rule from each layer grants access. */ allowed = true; |