Thread (12 messages) 12 messages, 2 authors, 2020-11-20
STALE2034d

[PATCH v1 5/9] landlock: Add extra checks when inserting a rule

From: Mickaël Salaün <mic@digikod.net>
Date: 2020-11-11 21:35:22
Also in: linux-doc, linux-kselftest, lkml
Subsystem: landlock security module, security subsystem, the rest · Maintainers: Mickaël Salaün, Paul Moore, James Morris, "Serge E. Hallyn", Linus Torvalds

Make sure that there is always an (allocated) object in each used rules.
This could have prevented the bug fixed with a previous commit.

When the rules from a ruleset are merged in a domain with
landlock_enforce_ruleset_current(2), these new rules should be assigned
to the last layer.  However, when a rule is just extending a ruleset
with landlock_add_rule(2), the number of layers of this updated ruleset
should always be 0.  Checking such use of landlock_insert_rule() could
enable to detect bugs in future developments.

Replace the hardcoded 1 with SINGLE_DEPTH_NESTING.

Cc: James Morris <jmorris@namei.org>
Cc: Jann Horn <jannh@google.com>
Cc: Serge E. Hallyn <serge@hallyn.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
---
 security/landlock/ruleset.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c
index 7654a66cea43..1fb85daeb750 100644
--- a/security/landlock/ruleset.c
+++ b/security/landlock/ruleset.c
@@ -102,6 +102,10 @@ int landlock_insert_rule(struct landlock_ruleset *const ruleset,
 
 	might_sleep();
 	lockdep_assert_held(&ruleset->lock);
+	if (WARN_ON_ONCE(!rule->object))
+		return -ENOENT;
+	if (!is_merge && WARN_ON_ONCE(ruleset->nb_layers != 0))
+		return -EINVAL;
 	walker_node = &(ruleset->root.rb_node);
 	while (*walker_node) {
 		struct landlock_rule *const this = rb_entry(*walker_node,
@@ -223,12 +227,7 @@ static struct landlock_ruleset *inherit_ruleset(
 		return new_ruleset;
 
 	mutex_lock(&new_ruleset->lock);
-	mutex_lock_nested(&parent->lock, 1);
-	new_ruleset->nb_layers = parent->nb_layers;
-	new_ruleset->fs_access_mask = parent->fs_access_mask;
-	WARN_ON_ONCE(!parent->hierarchy);
-	get_hierarchy(parent->hierarchy);
-	new_ruleset->hierarchy->parent = parent->hierarchy;
+	mutex_lock_nested(&parent->lock, SINGLE_DEPTH_NESTING);
 
 	/* Copies the @parent tree. */
 	rbtree_postorder_for_each_entry_safe(walker_rule, next_rule,
@@ -237,6 +236,12 @@ static struct landlock_ruleset *inherit_ruleset(
 		if (err)
 			goto out_unlock;
 	}
+	new_ruleset->nb_layers = parent->nb_layers;
+	new_ruleset->fs_access_mask = parent->fs_access_mask;
+	WARN_ON_ONCE(!parent->hierarchy);
+	get_hierarchy(parent->hierarchy);
+	new_ruleset->hierarchy->parent = parent->hierarchy;
+
 	mutex_unlock(&parent->lock);
 	mutex_unlock(&new_ruleset->lock);
 	return new_ruleset;
-- 
2.29.2
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help