Linux Security Modules development
 help / color / mirror / Atom feed
From: Justin Suess <utilityemal77@gmail.com>
To: gnoack3000@gmail.com, mic@digikod.net
Cc: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	Justin Suess <utilityemal77@gmail.com>
Subject: [PATCH v8 05/10] landlock: Return inserted rule from landlock_insert_rule()
Date: Thu, 28 May 2026 21:52:04 -0400	[thread overview]
Message-ID: <20260529015210.500291-6-utilityemal77@gmail.com> (raw)
In-Reply-To: <20260529015210.500291-1-utilityemal77@gmail.com>

Change insert_rule() and landlock_insert_rule() to return the inserted
(or updated) struct landlock_rule pointer instead of an int errno.
Errors are propagated via ERR_PTR().

This gives callers a handle on the resulting rule so a subsequent change
can mutate per-layer flags on it (e.g. to mark ancestor rules created
for no-inherit topology sealing).

No functional change intended.

Signed-off-by: Justin Suess <utilityemal77@gmail.com>
---

Notes:
    v7..v8 changes:
    
      * Replaced the v7 "Move find_rule definition above
        landlock_append_fs_rule" patch with this new preparatory patch.
        Instead of moving find_rule(), make landlock_insert_rule() (and
        its static insert_rule() helper) return the inserted struct
        landlock_rule * via ERR_PTR(), so callers can directly tag flags
        on the resulting rule. Callers in net.c, merge_tree(), and
        inherit_tree() updated accordingly. No functional change.

 security/landlock/fs.c      |  7 ++--
 security/landlock/net.c     |  8 +++--
 security/landlock/ruleset.c | 68 ++++++++++++++++++-------------------
 security/landlock/ruleset.h |  7 ++--
 4 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index 6552351e0b9c..ee7d9f5d7ee5 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -359,7 +359,8 @@ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset,
 			    const struct path *const path,
 			    access_mask_t access_rights, const int flags)
 {
-	int err;
+	int err = 0;
+	struct landlock_rule *rule;
 	struct landlock_id id = {
 		.type = LANDLOCK_KEY_INODE,
 	};
@@ -378,7 +379,9 @@ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset,
 	if (IS_ERR(id.key.object))
 		return PTR_ERR(id.key.object);
 	mutex_lock(&ruleset->lock);
-	err = landlock_insert_rule(ruleset, id, access_rights, flags);
+	rule = landlock_insert_rule(ruleset, id, access_rights, flags);
+	if (IS_ERR(rule))
+		err = PTR_ERR(rule);
 	mutex_unlock(&ruleset->lock);
 	/*
 	 * No need to check for an error because landlock_insert_rule()
diff --git a/security/landlock/net.c b/security/landlock/net.c
index 60894cff973e..f08be4be275a 100644
--- a/security/landlock/net.c
+++ b/security/landlock/net.c
@@ -23,11 +23,11 @@ int landlock_append_net_rule(struct landlock_ruleset *const ruleset,
 			     const u16 port, access_mask_t access_rights,
 			     const int flags)
 {
-	int err;
 	const struct landlock_id id = {
 		.key.data = (__force uintptr_t)htons(port),
 		.type = LANDLOCK_KEY_NET_PORT,
 	};
+	struct landlock_rule *rule;
 
 	BUILD_BUG_ON(sizeof(port) > sizeof(id.key.data));
 
@@ -36,10 +36,12 @@ int landlock_append_net_rule(struct landlock_ruleset *const ruleset,
 			 ~landlock_get_net_access_mask(ruleset, 0);
 
 	mutex_lock(&ruleset->lock);
-	err = landlock_insert_rule(ruleset, id, access_rights, flags);
+	rule = landlock_insert_rule(ruleset, id, access_rights, flags);
 	mutex_unlock(&ruleset->lock);
 
-	return err;
+	if (IS_ERR(rule))
+		return PTR_ERR(rule);
+	return 0;
 }
 
 static int current_check_access_socket(struct socket *const sock,
diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c
index f01c3e14e55d..48397ab43a2d 100644
--- a/security/landlock/ruleset.c
+++ b/security/landlock/ruleset.c
@@ -203,12 +203,13 @@ static void build_check_ruleset(void)
  * added to @ruleset as new constraints, similarly to a boolean AND between
  * access rights.
  *
- * Return: 0 on success, -errno on failure.
+ * Return: A pointer to the inserted or updated rule, or an ERR_PTR on failure.
  */
-static int insert_rule(struct landlock_ruleset *const ruleset,
-		       const struct landlock_id id,
-		       const struct landlock_layer (*layers)[],
-		       const size_t num_layers)
+static struct landlock_rule *
+insert_rule(struct landlock_ruleset *const ruleset,
+	    const struct landlock_id id,
+	    const struct landlock_layer (*layers)[],
+	    const size_t num_layers)
 {
 	struct rb_node **walker_node;
 	struct rb_node *parent_node = NULL;
@@ -218,14 +219,14 @@ static int insert_rule(struct landlock_ruleset *const ruleset,
 	might_sleep();
 	lockdep_assert_held(&ruleset->lock);
 	if (WARN_ON_ONCE(!layers))
-		return -ENOENT;
+		return ERR_PTR(-ENOENT);
 
 	if (is_object_pointer(id.type) && WARN_ON_ONCE(!id.key.object))
-		return -ENOENT;
+		return ERR_PTR(-ENOENT);
 
 	root = get_root(ruleset, id.type);
 	if (IS_ERR(root))
-		return PTR_ERR(root);
+		return ERR_CAST(root);
 
 	walker_node = &root->rb_node;
 	while (*walker_node) {
@@ -243,7 +244,7 @@ static int insert_rule(struct landlock_ruleset *const ruleset,
 
 		/* Only a single-level layer should match an existing rule. */
 		if (WARN_ON_ONCE(num_layers != 1))
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 
 		/* If there is a matching rule, updates it. */
 		if ((*layers)[0].level == 0) {
@@ -252,16 +253,16 @@ static int insert_rule(struct landlock_ruleset *const ruleset,
 			 * landlock_add_rule(2), i.e. @ruleset is not a domain.
 			 */
 			if (WARN_ON_ONCE(this->num_layers != 1))
-				return -EINVAL;
+				return ERR_PTR(-EINVAL);
 			if (WARN_ON_ONCE(this->layers[0].level != 0))
-				return -EINVAL;
+				return ERR_PTR(-EINVAL);
 			this->layers[0].access |= (*layers)[0].access;
 			this->layers[0].flags.quiet |= (*layers)[0].flags.quiet;
-			return 0;
+			return this;
 		}
 
 		if (WARN_ON_ONCE(this->layers[0].level == 0))
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 
 		/*
 		 * Intersects access rights when it is a merge between a
@@ -270,23 +271,23 @@ static int insert_rule(struct landlock_ruleset *const ruleset,
 		new_rule = create_rule(id, &this->layers, this->num_layers,
 				       &(*layers)[0]);
 		if (IS_ERR(new_rule))
-			return PTR_ERR(new_rule);
+			return ERR_CAST(new_rule);
 		rb_replace_node(&this->node, &new_rule->node, root);
 		free_rule(this, id.type);
-		return 0;
+		return new_rule;
 	}
 
 	/* There is no match for @id. */
 	build_check_ruleset();
 	if (ruleset->num_rules >= LANDLOCK_MAX_NUM_RULES)
-		return -E2BIG;
+		return ERR_PTR(-E2BIG);
 	new_rule = create_rule(id, layers, num_layers, NULL);
 	if (IS_ERR(new_rule))
-		return PTR_ERR(new_rule);
+		return ERR_CAST(new_rule);
 	rb_link_node(&new_rule->node, parent_node, walker_node);
 	rb_insert_color(&new_rule->node, root);
 	ruleset->num_rules++;
-	return 0;
+	return new_rule;
 }
 
 static void build_check_layer(void)
@@ -305,9 +306,10 @@ static void build_check_layer(void)
 }
 
 /* @ruleset must be locked by the caller. */
-int landlock_insert_rule(struct landlock_ruleset *const ruleset,
-			 const struct landlock_id id,
-			 const access_mask_t access, const int flags)
+struct landlock_rule *
+landlock_insert_rule(struct landlock_ruleset *const ruleset,
+		     const struct landlock_id id,
+		     const access_mask_t access, const int flags)
 {
 	struct landlock_layer layers[] = { {
 		.access = access,
@@ -326,9 +328,8 @@ static int merge_tree(struct landlock_ruleset *const dst,
 		      struct landlock_ruleset *const src,
 		      const enum landlock_key_type key_type)
 {
-	struct landlock_rule *walker_rule, *next_rule;
+	struct landlock_rule *walker_rule, *next_rule, *rule;
 	struct rb_root *src_root;
-	int err = 0;
 
 	might_sleep();
 	lockdep_assert_held(&dst->lock);
@@ -358,11 +359,11 @@ static int merge_tree(struct landlock_ruleset *const dst,
 		layers[0].access = walker_rule->layers[0].access;
 		layers[0].flags = walker_rule->layers[0].flags;
 
-		err = insert_rule(dst, id, &layers, ARRAY_SIZE(layers));
-		if (err)
-			return err;
+		rule = insert_rule(dst, id, &layers, ARRAY_SIZE(layers));
+		if (IS_ERR(rule))
+			return PTR_ERR(rule);
 	}
-	return err;
+	return 0;
 }
 
 static int merge_ruleset(struct landlock_ruleset *const dst,
@@ -412,9 +413,8 @@ static int inherit_tree(struct landlock_ruleset *const parent,
 			struct landlock_ruleset *const child,
 			const enum landlock_key_type key_type)
 {
-	struct landlock_rule *walker_rule, *next_rule;
+	struct landlock_rule *walker_rule, *next_rule, *rule;
 	struct rb_root *parent_root;
-	int err = 0;
 
 	might_sleep();
 	lockdep_assert_held(&parent->lock);
@@ -432,12 +432,12 @@ static int inherit_tree(struct landlock_ruleset *const parent,
 			.type = key_type,
 		};
 
-		err = insert_rule(child, id, &walker_rule->layers,
-				  walker_rule->num_layers);
-		if (err)
-			return err;
+		rule = insert_rule(child, id, &walker_rule->layers,
+				   walker_rule->num_layers);
+		if (IS_ERR(rule))
+			return PTR_ERR(rule);
 	}
-	return err;
+	return 0;
 }
 
 static int inherit_ruleset(struct landlock_ruleset *const parent,
diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h
index ff163e5db5f0..5b7f554e8442 100644
--- a/security/landlock/ruleset.h
+++ b/security/landlock/ruleset.h
@@ -217,9 +217,10 @@ void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset);
 DEFINE_FREE(landlock_put_ruleset, struct landlock_ruleset *,
 	    if (!IS_ERR_OR_NULL(_T)) landlock_put_ruleset(_T))
 
-int landlock_insert_rule(struct landlock_ruleset *const ruleset,
-			 const struct landlock_id id,
-			 const access_mask_t access, const int flags);
+struct landlock_rule *
+landlock_insert_rule(struct landlock_ruleset *const ruleset,
+		     const struct landlock_id id,
+		     const access_mask_t access, const int flags);
 
 struct landlock_ruleset *
 landlock_merge_ruleset(struct landlock_ruleset *const parent,
-- 
2.53.0


  parent reply	other threads:[~2026-05-29  1:52 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-29  1:51 [PATCH v8 00/10] Implement LANDLOCK_ADD_RULE_NO_INHERIT Justin Suess
2026-05-29  1:52 ` [PATCH v8 01/10] landlock: Add landlock_walk_path_up() helper Justin Suess
2026-05-29  1:52 ` [PATCH v8 02/10] landlock: Use landlock_walk_path_up() in is_access_to_paths_allowed() Justin Suess
2026-05-29  1:52 ` [PATCH v8 03/10] landlock: Use landlock_walk_path_up() in collect_domain_accesses() Justin Suess
2026-05-29  1:52 ` [PATCH v8 04/10] landlock: Add LANDLOCK_ADD_RULE_NO_INHERIT user API Justin Suess
2026-05-29  1:52 ` Justin Suess [this message]
2026-05-29  1:52 ` [PATCH v8 06/10] landlock: Implement LANDLOCK_ADD_RULE_NO_INHERIT Justin Suess
2026-05-29  1:52 ` [PATCH v8 07/10] landlock: Add documentation for LANDLOCK_ADD_RULE_NO_INHERIT Justin Suess
2026-05-29  1:52 ` [PATCH v8 08/10] samples/landlock: Add LANDLOCK_ADD_RULE_NO_INHERIT to landlock-sandboxer Justin Suess
2026-05-29  1:52 ` [PATCH v8 09/10] selftests/landlock: Add selftests for LANDLOCK_ADD_RULE_NO_INHERIT Justin Suess
2026-05-29  1:52 ` [PATCH v8 10/10] landlock: Add KUnit tests " Justin Suess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260529015210.500291-6-utilityemal77@gmail.com \
    --to=utilityemal77@gmail.com \
    --cc=gnoack3000@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox