diff options
author | Mickaël Salaün <mic@digikod.net> | 2025-01-08 16:43:14 +0100 |
---|---|---|
committer | Mickaël Salaün <mic@digikod.net> | 2025-01-17 19:05:35 +0100 |
commit | d6c7cf84a24fff332ff65ffe236302216474b834 (patch) | |
tree | ef6e97a53cee0b4805aed2b41d35010668bcac1c /security | |
parent | 622e2f5954763385c4fa1f9a11a11366952a9b60 (diff) |
landlock: Simplify initially denied access rights
Upgrade domain's handled access masks when creating a domain from a
ruleset, instead of converting them at runtime. This is more consistent
and helps with audit support.
Cc: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20250108154338.1129069-7-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Diffstat (limited to 'security')
-rw-r--r-- | security/landlock/access.h | 17 | ||||
-rw-r--r-- | security/landlock/fs.c | 10 | ||||
-rw-r--r-- | security/landlock/ruleset.c | 3 |
3 files changed, 19 insertions, 11 deletions
diff --git a/security/landlock/access.h b/security/landlock/access.h index 9ee4b30a87e6..74fd8f399fbd 100644 --- a/security/landlock/access.h +++ b/security/landlock/access.h @@ -20,7 +20,8 @@ /* * All access rights that are denied by default whether they are handled or not * by a ruleset/layer. This must be ORed with all ruleset->access_masks[] - * entries when we need to get the absolute handled access masks. + * entries when we need to get the absolute handled access masks, see + * landlock_upgrade_handled_access_masks(). */ /* clang-format off */ #define _LANDLOCK_ACCESS_FS_INITIALLY_DENIED ( \ @@ -59,4 +60,18 @@ typedef u16 layer_mask_t; /* Makes sure all layers can be checked. */ static_assert(BITS_PER_TYPE(layer_mask_t) >= LANDLOCK_MAX_NUM_LAYERS); +/* Upgrades with all initially denied by default access rights. */ +static inline struct access_masks +landlock_upgrade_handled_access_masks(struct access_masks access_masks) +{ + /* + * All access rights that are denied by default whether they are + * explicitly handled or not. + */ + if (access_masks.fs) + access_masks.fs |= _LANDLOCK_ACCESS_FS_INITIALLY_DENIED; + + return access_masks; +} + #endif /* _SECURITY_LANDLOCK_ACCESS_H */ diff --git a/security/landlock/fs.c b/security/landlock/fs.c index e323f7fb5a98..4eb972f2292f 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -389,14 +389,6 @@ static bool is_nouser_or_private(const struct dentry *dentry) unlikely(IS_PRIVATE(d_backing_inode(dentry)))); } -static access_mask_t -get_handled_fs_accesses(const struct landlock_ruleset *const domain) -{ - /* Handles all initially denied by default access rights. */ - return landlock_union_access_masks(domain).fs | - _LANDLOCK_ACCESS_FS_INITIALLY_DENIED; -} - static const struct access_masks any_fs = { .fs = ~0, }; @@ -788,7 +780,7 @@ static bool is_access_to_paths_allowed( * a superset of the meaningful requested accesses). */ access_masked_parent1 = access_masked_parent2 = - get_handled_fs_accesses(domain); + landlock_union_access_masks(domain).fs; is_dom_check = true; } else { if (WARN_ON_ONCE(dentry_child1 || dentry_child2)) diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c index 4aeab215d7c5..241ce44375b6 100644 --- a/security/landlock/ruleset.c +++ b/security/landlock/ruleset.c @@ -387,7 +387,8 @@ static int merge_ruleset(struct landlock_ruleset *const dst, err = -EINVAL; goto out_unlock; } - dst->access_masks[dst->num_layers - 1] = src->access_masks[0]; + dst->access_masks[dst->num_layers - 1] = + landlock_upgrade_handled_access_masks(src->access_masks[0]); /* Merges the @src inode tree. */ err = merge_tree(dst, src, LANDLOCK_KEY_INODE); |