All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
To: <mic@digikod.net>
Cc: <willemdebruijn.kernel@gmail.com>, <gnoack3000@gmail.com>,
	<linux-security-module@vger.kernel.org>, <netdev@vger.kernel.org>,
	<netfilter-devel@vger.kernel.org>, <artem.kuzin@huawei.com>
Subject: [PATCH v8 04/12] landlock: Move unmask_layers() and init_layer_masks()
Date: Fri, 21 Oct 2022 23:26:36 +0800	[thread overview]
Message-ID: <20221021152644.155136-5-konstantin.meskhidze@huawei.com> (raw)
In-Reply-To: <20221021152644.155136-1-konstantin.meskhidze@huawei.com>

This patch moves unmask_layers() and init_layer_masks() helpers
to ruleset.c to share with landlock network implementation in
following commits.

Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
---

Changes since v7:
* Refactors commit message.

Changes since v6:
* Moves get_handled_accesses() helper from ruleset.c back to fs.c,
  cause it's not used in coming network commits.

Changes since v5:
* Splits commit.
* Moves init_layer_masks() and get_handled_accesses() helpers
to ruleset.c and makes then non-static.
* Formats code with clang-format-14.

---
 security/landlock/fs.c      | 103 ------------------------------------
 security/landlock/ruleset.c | 102 +++++++++++++++++++++++++++++++++++
 security/landlock/ruleset.h |  20 +++++++
 3 files changed, 122 insertions(+), 103 deletions(-)

diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index 710cfa1306de..240e42a8f788 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -226,60 +226,6 @@ find_rule(const struct landlock_ruleset *const domain,
 	return rule;
 }

-/*
- * @layer_masks is read and may be updated according to the access request and
- * the matching rule.
- *
- * Returns true if the request is allowed (i.e. relevant layer masks for the
- * request are empty).
- */
-static inline bool
-unmask_layers(const struct landlock_rule *const rule,
-	      const access_mask_t access_request,
-	      layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS])
-{
-	size_t layer_level;
-
-	if (!access_request || !layer_masks)
-		return true;
-	if (!rule)
-		return false;
-
-	/*
-	 * An access is granted if, for each policy layer, at least one rule
-	 * encountered on the pathwalk grants the requested access,
-	 * regardless of its position in the layer stack.  We must then check
-	 * the remaining layers for each inode, from the first added layer to
-	 * the last one.  When there is multiple requested accesses, for each
-	 * policy layer, the full set of requested accesses may not be granted
-	 * by only one rule, but by the union (binary OR) of multiple rules.
-	 * E.g. /a/b <execute> + /a <read> => /a/b <execute + read>
-	 */
-	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);
-		const unsigned long access_req = access_request;
-		unsigned long access_bit;
-		bool is_empty;
-
-		/*
-		 * Records in @layer_masks which layer grants access to each
-		 * requested access.
-		 */
-		is_empty = true;
-		for_each_set_bit(access_bit, &access_req,
-				 ARRAY_SIZE(*layer_masks)) {
-			if (layer->access & BIT_ULL(access_bit))
-				(*layer_masks)[access_bit] &= ~layer_bit;
-			is_empty = is_empty && !(*layer_masks)[access_bit];
-		}
-		if (is_empty)
-			return true;
-	}
-	return false;
-}
-
 /*
  * Allows access to pseudo filesystems that will never be mountable (e.g.
  * sockfs, pipefs), but can still be reachable through
@@ -303,55 +249,6 @@ get_handled_accesses(const struct landlock_ruleset *const domain)
 	return access_dom & LANDLOCK_MASK_ACCESS_FS;
 }

-/**
- * init_layer_masks - Initialize layer masks from an access request
- *
- * Populates @layer_masks such that for each access right in @access_request,
- * the bits for all the layers are set where this access right is handled.
- *
- * @domain: The domain that defines the current restrictions.
- * @access_request: The requested access rights to check.
- * @layer_masks: The layer masks to populate.
- *
- * Returns: An access mask where each access right bit is set which is handled
- * in any of the active layers in @domain.
- */
-static inline access_mask_t
-init_layer_masks(const struct landlock_ruleset *const domain,
-		 const access_mask_t access_request,
-		 layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS])
-{
-	access_mask_t handled_accesses = 0;
-	size_t layer_level;
-
-	memset(layer_masks, 0, sizeof(*layer_masks));
-	/* An empty access request can happen because of O_WRONLY | O_RDWR. */
-	if (!access_request)
-		return 0;
-
-	/* Saves all handled accesses per layer. */
-	for (layer_level = 0; layer_level < domain->num_layers; layer_level++) {
-		const unsigned long access_req = access_request;
-		unsigned long access_bit;
-
-		for_each_set_bit(access_bit, &access_req,
-				 ARRAY_SIZE(*layer_masks)) {
-			/*
-			 * Artificially handles all initially denied by default
-			 * access rights.
-			 */
-			if (BIT_ULL(access_bit) &
-			    (landlock_get_fs_access_mask(domain, layer_level) |
-			     ACCESS_INITIALLY_DENIED)) {
-				(*layer_masks)[access_bit] |=
-					BIT_ULL(layer_level);
-				handled_accesses |= BIT_ULL(access_bit);
-			}
-		}
-	}
-	return handled_accesses;
-}
-
 /*
  * Check that a destination file hierarchy has more restrictions than a source
  * file hierarchy.  This is only used for link and rename actions.
diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c
index 961ffe0c709e..02ab14439c43 100644
--- a/security/landlock/ruleset.c
+++ b/security/landlock/ruleset.c
@@ -572,3 +572,105 @@ landlock_find_rule(const struct landlock_ruleset *const ruleset,
 	}
 	return NULL;
 }
+
+/*
+ * @layer_masks is read and may be updated according to the access request and
+ * the matching rule.
+ *
+ * Returns true if the request is allowed (i.e. relevant layer masks for the
+ * request are empty).
+ */
+bool unmask_layers(const struct landlock_rule *const rule,
+		   const access_mask_t access_request,
+		   layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS])
+{
+	size_t layer_level;
+
+	if (!access_request || !layer_masks)
+		return true;
+	if (!rule)
+		return false;
+
+	/*
+	 * An access is granted if, for each policy layer, at least one rule
+	 * encountered on the pathwalk grants the requested access,
+	 * regardless of its position in the layer stack.  We must then check
+	 * the remaining layers for each inode, from the first added layer to
+	 * the last one.  When there is multiple requested accesses, for each
+	 * policy layer, the full set of requested accesses may not be granted
+	 * by only one rule, but by the union (binary OR) of multiple rules.
+	 * E.g. /a/b <execute> + /a <read> => /a/b <execute + read>
+	 */
+	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);
+		const unsigned long access_req = access_request;
+		unsigned long access_bit;
+		bool is_empty;
+
+		/*
+		 * Records in @layer_masks which layer grants access to each
+		 * requested access.
+		 */
+		is_empty = true;
+		for_each_set_bit(access_bit, &access_req,
+				 ARRAY_SIZE(*layer_masks)) {
+			if (layer->access & BIT_ULL(access_bit))
+				(*layer_masks)[access_bit] &= ~layer_bit;
+			is_empty = is_empty && !(*layer_masks)[access_bit];
+		}
+		if (is_empty)
+			return true;
+	}
+	return false;
+}
+
+/**
+ * init_layer_masks - Initialize layer masks from an access request
+ *
+ * Populates @layer_masks such that for each access right in @access_request,
+ * the bits for all the layers are set where this access right is handled.
+ *
+ * @domain: The domain that defines the current restrictions.
+ * @access_request: The requested access rights to check.
+ * @layer_masks: The layer masks to populate.
+ *
+ * Returns: An access mask where each access right bit is set which is handled
+ * in any of the active layers in @domain.
+ */
+access_mask_t
+init_layer_masks(const struct landlock_ruleset *const domain,
+		 const access_mask_t access_request,
+		 layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS])
+{
+	access_mask_t handled_accesses = 0;
+	size_t layer_level;
+
+	memset(layer_masks, 0, sizeof(*layer_masks));
+	/* An empty access request can happen because of O_WRONLY | O_RDWR. */
+	if (!access_request)
+		return 0;
+
+	/* Saves all handled accesses per layer. */
+	for (layer_level = 0; layer_level < domain->num_layers; layer_level++) {
+		const unsigned long access_req = access_request;
+		unsigned long access_bit;
+
+		for_each_set_bit(access_bit, &access_req,
+				 ARRAY_SIZE(*layer_masks)) {
+			/*
+			 * Artificially handles all initially denied by default
+			 * access rights.
+			 */
+			if (BIT_ULL(access_bit) &
+			    (landlock_get_fs_access_mask(domain, layer_level) |
+			     ACCESS_INITIALLY_DENIED)) {
+				(*layer_masks)[access_bit] |=
+					BIT_ULL(layer_level);
+				handled_accesses |= BIT_ULL(access_bit);
+			}
+		}
+	}
+	return handled_accesses;
+}
diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h
index 608ab356bc3e..50baff4fcbb4 100644
--- a/security/landlock/ruleset.h
+++ b/security/landlock/ruleset.h
@@ -34,6 +34,16 @@ typedef u16 layer_mask_t;
 /* Makes sure all layers can be checked. */
 static_assert(BITS_PER_TYPE(layer_mask_t) >= LANDLOCK_MAX_NUM_LAYERS);

+/*
+ * 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->fs_access_masks[]
+ * entries when we need to get the absolute handled access masks.
+ */
+/* clang-format off */
+#define ACCESS_INITIALLY_DENIED ( \
+	LANDLOCK_ACCESS_FS_REFER)
+/* clang-format on */
+
 /**
  * struct landlock_layer - Access rights for a given layer
  */
@@ -246,4 +256,14 @@ landlock_get_fs_access_mask(const struct landlock_ruleset *const ruleset,
 		LANDLOCK_SHIFT_ACCESS_FS) &
 	       LANDLOCK_MASK_ACCESS_FS;
 }
+
+bool unmask_layers(const struct landlock_rule *const rule,
+		   const access_mask_t access_request,
+		   layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS]);
+
+access_mask_t
+init_layer_masks(const struct landlock_ruleset *const domain,
+		 const access_mask_t access_request,
+		 layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS]);
+
 #endif /* _SECURITY_LANDLOCK_RULESET_H */
--
2.25.1


  parent reply	other threads:[~2022-10-21 15:27 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-21 15:26 [PATCH v8 00/12] Network support for Landlock Konstantin Meskhidze
2022-10-21 15:26 ` [PATCH v8 01/12] landlock: Make ruleset's access masks more generic Konstantin Meskhidze
2022-11-17 18:41   ` Mickaël Salaün
2022-11-28  2:53     ` Konstantin Meskhidze (A)
2022-11-28 20:22       ` Mickaël Salaün
2022-12-02  2:49         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 02/12] landlock: Refactor landlock_find_rule/insert_rule Konstantin Meskhidze
2022-11-17 18:41   ` Mickaël Salaün
2022-11-17 18:55     ` [PATCH] landlock: Allow filesystem layout changes for domains without such rule type Mickaël Salaün
2022-11-18  9:16       ` Mickaël Salaün
2022-11-28  3:04         ` Konstantin Meskhidze (A)
2022-11-28 20:23           ` Mickaël Salaün
2022-12-02  2:50             ` Konstantin Meskhidze (A)
2022-12-24  3:10             ` Konstantin Meskhidze (A)
2022-12-26 21:24               ` Mickaël Salaün
2022-12-27  1:47                 ` Konstantin Meskhidze (A)
2022-11-28  3:02       ` Konstantin Meskhidze (A)
2022-11-28 20:25         ` Mickaël Salaün
2022-12-02  2:51           ` Konstantin Meskhidze (A)
2022-11-22 17:17     ` [PATCH v8 02/12] landlock: Refactor landlock_find_rule/insert_rule Mickaël Salaün
2022-11-28  3:06       ` Konstantin Meskhidze (A)
2022-11-28  2:58     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 03/12] landlock: Refactor merge/inherit_ruleset functions Konstantin Meskhidze
2022-11-17 18:41   ` Mickaël Salaün
2022-11-28  3:07     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` Konstantin Meskhidze [this message]
2022-11-17 18:42   ` [PATCH v8 04/12] landlock: Move unmask_layers() and init_layer_masks() Mickaël Salaün
2022-11-28  3:25     ` Konstantin Meskhidze (A)
2022-11-28 20:25       ` Mickaël Salaün
2022-12-02  2:52         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 05/12] landlock: Refactor " Konstantin Meskhidze
2022-11-17 18:42   ` Mickaël Salaün
2022-11-28  3:30     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 06/12] landlock: Refactor landlock_add_rule() syscall Konstantin Meskhidze
2022-11-17 18:42   ` Mickaël Salaün
2022-11-28  3:32     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 07/12] landlock: Add network rules support Konstantin Meskhidze
2022-11-17 18:43   ` Mickaël Salaün
2022-11-28  4:01     ` Konstantin Meskhidze (A)
2022-11-28 20:26       ` Mickaël Salaün
2022-12-02  2:54         ` Konstantin Meskhidze (A)
2023-01-03 12:44     ` Konstantin Meskhidze (A)
2023-01-04 11:41     ` Konstantin Meskhidze (A)
2023-01-06 19:22       ` Mickaël Salaün
2023-01-09  7:59         ` Konstantin Meskhidze (A)
2023-01-09  8:58           ` Dan Carpenter
2023-01-09  9:26             ` Konstantin Meskhidze (A)
2023-01-09 10:20               ` Dan Carpenter
2023-01-09 11:39                 ` Konstantin Meskhidze (A)
2023-01-09 11:53                   ` Dan Carpenter
2023-01-09 12:18                     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 08/12] landlock: Implement TCP network hooks Konstantin Meskhidze
2022-11-17 18:43   ` Mickaël Salaün
2022-11-28  8:21     ` Konstantin Meskhidze (A)
2022-11-28 21:00       ` Mickaël Salaün
2022-12-02  3:13         ` Konstantin Meskhidze (A)
2022-12-02 13:01           ` Mickaël Salaün
2022-12-05  2:55             ` Konstantin Meskhidze (A)
2022-12-05 13:18               ` Mickaël Salaün
2023-01-05  8:57     ` Konstantin Meskhidze (A)
2023-01-06 19:30       ` Mickaël Salaün
2023-01-09  8:07         ` Konstantin Meskhidze (A)
2023-01-09 12:38           ` Mickaël Salaün
2023-01-10  4:45             ` Konstantin Meskhidze (A)
2023-01-10 17:24               ` Mickaël Salaün
2023-01-11  1:54                 ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 09/12] selftests/landlock: Share enforce_ruleset() Konstantin Meskhidze
2022-11-17 18:43   ` Mickaël Salaün
2022-11-28  4:02     ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 10/12] selftests/landlock: Add 10 new test suites dedicated to network Konstantin Meskhidze
2023-01-09 12:46   ` Mickaël Salaün
2023-01-10  5:03     ` Konstantin Meskhidze (A)
2023-01-10 17:40       ` Mickaël Salaün
2023-01-11  1:52         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 11/12] samples/landlock: Add network demo Konstantin Meskhidze
2022-11-16 14:25   ` Mickaël Salaün
2022-11-28  2:49     ` Konstantin Meskhidze (A)
2022-11-28 20:26       ` Mickaël Salaün
2022-12-02  2:48         ` Konstantin Meskhidze (A)
2023-01-05  3:46     ` Konstantin Meskhidze (A)
2023-01-06 19:34       ` Mickaël Salaün
2023-01-09  7:57         ` Konstantin Meskhidze (A)
2022-10-21 15:26 ` [PATCH v8 12/12] landlock: Document Landlock's network support Konstantin Meskhidze
2022-11-17 18:44   ` Mickaël Salaün
2022-11-28  6:44     ` Konstantin Meskhidze (A)
2022-11-28 20:26       ` Mickaël Salaün
2022-12-02  3:14         ` Konstantin Meskhidze (A)

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=20221021152644.155136-5-konstantin.meskhidze@huawei.com \
    --to=konstantin.meskhidze@huawei.com \
    --cc=artem.kuzin@huawei.com \
    --cc=gnoack3000@gmail.com \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=willemdebruijn.kernel@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.