]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
landlock: Simplify initially denied access rights
authorMickaël Salaün <mic@digikod.net>
Wed, 8 Jan 2025 15:43:14 +0000 (16:43 +0100)
committerMickaël Salaün <mic@digikod.net>
Fri, 17 Jan 2025 18:05:35 +0000 (19:05 +0100)
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>
security/landlock/access.h
security/landlock/fs.c
security/landlock/ruleset.c

index 9ee4b30a87e67c6bc1987eeed0124abdc72bffed..74fd8f399fbd6dd6e36ad335a91cc6c8d0bd5c11 100644 (file)
@@ -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 */
index e323f7fb5a98aa841b9da6765ee9a495c6b8e05f..4eb972f2292ff5e5b5e4c33941cc168d9f4ce325 100644 (file)
@@ -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))
index 4aeab215d7c533bd5a90149e42c13e4ce3047f9d..241ce44375b6a9cbc9012856e8714cfc398ba6ad 100644 (file)
@@ -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);