All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fan Wu <wufan@linux.microsoft.com>
To: corbet@lwn.net, zohar@linux.ibm.com, jmorris@namei.org,
	serge@hallyn.com, tytso@mit.edu, ebiggers@kernel.org,
	axboe@kernel.dk, agk@redhat.com, snitzer@kernel.org,
	eparis@redhat.com, paul@paul-moore.com
Cc: linux-doc@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-fscrypt@vger.kernel.org, linux-block@vger.kernel.org,
	dm-devel@lists.linux.dev, audit@vger.kernel.org,
	linux-kernel@vger.kernel.org, Fan Wu <wufan@linux.microsoft.com>,
	Deven Bowers <deven.desai@linux.microsoft.com>
Subject: [RFC PATCH v12 06/20] ipe: introduce 'boot_verified' as a trust provider
Date: Tue, 30 Jan 2024 14:36:54 -0800	[thread overview]
Message-ID: <1706654228-17180-7-git-send-email-wufan@linux.microsoft.com> (raw)
In-Reply-To: <1706654228-17180-1-git-send-email-wufan@linux.microsoft.com>

IPE is designed to provide system level trust guarantees, this usually
implies that trust starts from bootup with a hardware root of trust,
which validates the bootloader. After this, the bootloader verifies
the kernel and the initramfs.

As there's no currently supported integrity method for initramfs, and
it's typically already verified by the bootloader. This patch introduces
a new IPE property `boot_verified` which allows author of IPE policy to
indicate trust for files from initramfs.

The implementation of this feature utilizes the newly added
`unpack_initramfs` hook. This hook marks the superblock of the rootfs
after the initramfs has been unpacked into it.

Since the rootfs is never unmounted during system operation, it is
advised to switch to a different policy that doesn't rely on the
`boot_verified` property after the real rootfs is in charge.
This ensures that the trust policies remain relevant and effective
throughout the system's operation.

Signed-off-by: Deven Bowers <deven.desai@linux.microsoft.com>
Signed-off-by: Fan Wu <wufan@linux.microsoft.com>

---
v2:
  +No Changes

v3:
  + Remove useless caching system
  + Move ipe_load_properties to this match
  + Minor changes from checkpatch --strict warnings

v4:
  + Remove comments from headers that was missed previously.
  + Grammatical corrections.

v5:
  + No significant changes

v6:
  + No changes

v7:
  + Reword and refactor patch 04/12 to [09/16], based on changes in
the underlying system.
  + Add common audit function for boolean values
  + Use common audit function as implementation.

v8:
  + No changes

v9:
  + No changes

v10:
  + Replace struct file with struct super_block

v11:
  + Fix code style issues

v12:
  + Switch to use unpack_initramfs hook and security blob
---
 security/ipe/eval.c          | 68 +++++++++++++++++++++++++++++++++++-
 security/ipe/eval.h          |  9 +++++
 security/ipe/hooks.c         |  8 +++++
 security/ipe/hooks.h         |  4 +++
 security/ipe/ipe.c           | 14 ++++++++
 security/ipe/ipe.h           |  3 ++
 security/ipe/policy.h        |  2 ++
 security/ipe/policy_parser.c | 37 +++++++++++++++++++-
 8 files changed, 143 insertions(+), 2 deletions(-)

diff --git a/security/ipe/eval.c b/security/ipe/eval.c
index 4f425afffcad..546bbc52a071 100644
--- a/security/ipe/eval.c
+++ b/security/ipe/eval.c
@@ -16,6 +16,24 @@
 
 struct ipe_policy __rcu *ipe_active_policy;
 
+#define FILE_SUPERBLOCK(f) ((f)->f_path.mnt->mnt_sb)
+
+#ifdef CONFIG_BLK_DEV_INITRD
+/**
+ * build_ipe_sb_ctx - Build from_initramfs field of an evaluation context.
+ * @ctx: Supplies a pointer to the context to be populated.
+ * @file: Supplies the file struct of the file triggered IPE event.
+ */
+static void build_ipe_sb_ctx(struct ipe_eval_ctx *ctx, const struct file *const file)
+{
+	ctx->from_initramfs = ipe_sb(FILE_SUPERBLOCK(file))->is_initramfs;
+}
+#else
+static void build_ipe_sb_ctx(struct ipe_eval_ctx *ctx, const struct file *const file)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 /**
  * build_eval_ctx - Build an evaluation context.
  * @ctx: Supplies a pointer to the context to be populated.
@@ -28,8 +46,49 @@ void build_eval_ctx(struct ipe_eval_ctx *ctx,
 {
 	ctx->file = file;
 	ctx->op = op;
+
+	if (file)
+		build_ipe_sb_ctx(ctx, file);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+/**
+ * evaluate_boot_verified_true - Evaluate @ctx for the boot verified property.
+ * @ctx: Supplies a pointer to the context being evaluated.
+ *
+ * Return:
+ * * true	- The current @ctx match the @p
+ * * false	- The current @ctx doesn't match the @p
+ */
+static bool evaluate_boot_verified_true(const struct ipe_eval_ctx *const ctx)
+{
+	return ctx->from_initramfs;
 }
 
+/**
+ * evaluate_boot_verified_false - Evaluate @ctx for the boot verified property.
+ * @ctx: Supplies a pointer to the context being evaluated.
+ *
+ * Return:
+ * * true	- The current @ctx match the @p
+ * * false	- The current @ctx doesn't match the @p
+ */
+static bool evaluate_boot_verified_false(const struct ipe_eval_ctx *const ctx)
+{
+	return !evaluate_boot_verified_true(ctx);
+}
+#else
+static bool evaluate_boot_verified_true(const struct ipe_eval_ctx *const ctx)
+{
+	return false;
+}
+
+static bool evaluate_boot_verified_false(const struct ipe_eval_ctx *const ctx)
+{
+	return false;
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 /**
  * evaluate_property - Analyze @ctx against a property.
  * @ctx: Supplies a pointer to the context to be evaluated.
@@ -42,7 +101,14 @@ void build_eval_ctx(struct ipe_eval_ctx *ctx,
 static bool evaluate_property(const struct ipe_eval_ctx *const ctx,
 			      struct ipe_prop *p)
 {
-	return false;
+	switch (p->type) {
+	case IPE_PROP_BOOT_VERIFIED_FALSE:
+		return evaluate_boot_verified_false(ctx);
+	case IPE_PROP_BOOT_VERIFIED_TRUE:
+		return evaluate_boot_verified_true(ctx);
+	default:
+		return false;
+	}
 }
 
 /**
diff --git a/security/ipe/eval.h b/security/ipe/eval.h
index cfdf3c8dfe8a..7d79fdb63bbf 100644
--- a/security/ipe/eval.h
+++ b/security/ipe/eval.h
@@ -15,10 +15,19 @@
 
 extern struct ipe_policy __rcu *ipe_active_policy;
 
+#ifdef CONFIG_BLK_DEV_INITRD
+struct ipe_sb {
+	bool is_initramfs;
+};
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 struct ipe_eval_ctx {
 	enum ipe_op_type op;
 
 	const struct file *file;
+#ifdef CONFIG_BLK_DEV_INITRD
+	bool from_initramfs;
+#endif /* CONFIG_BLK_DEV_INITRD */
 };
 
 void build_eval_ctx(struct ipe_eval_ctx *ctx, const struct file *file, enum ipe_op_type op);
diff --git a/security/ipe/hooks.c b/security/ipe/hooks.c
index 3aec88c074e1..8ee105bf7bad 100644
--- a/security/ipe/hooks.c
+++ b/security/ipe/hooks.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/fs_struct.h>
 #include <linux/types.h>
 #include <linux/binfmts.h>
 #include <linux/mman.h>
@@ -181,3 +182,10 @@ int ipe_kernel_load_data(enum kernel_load_data_id id, bool contents)
 	build_eval_ctx(&ctx, NULL, op);
 	return ipe_evaluate_event(&ctx);
 }
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void ipe_unpack_initramfs(void)
+{
+	ipe_sb(current->fs->root.mnt->mnt_sb)->is_initramfs = true;
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
diff --git a/security/ipe/hooks.h b/security/ipe/hooks.h
index 23205452f758..3b1bb0a6e89c 100644
--- a/security/ipe/hooks.h
+++ b/security/ipe/hooks.h
@@ -22,4 +22,8 @@ int ipe_kernel_read_file(struct file *file, enum kernel_read_file_id id,
 
 int ipe_kernel_load_data(enum kernel_load_data_id id, bool contents);
 
+#ifdef CONFIG_BLK_DEV_INITRD
+void ipe_unpack_initramfs(void);
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 #endif /* _IPE_HOOKS_H */
diff --git a/security/ipe/ipe.c b/security/ipe/ipe.c
index 22bd95116087..ed3acf6174d8 100644
--- a/security/ipe/ipe.c
+++ b/security/ipe/ipe.c
@@ -5,9 +5,13 @@
 #include <uapi/linux/lsm.h>
 
 #include "ipe.h"
+#include "eval.h"
 #include "hooks.h"
 
 static struct lsm_blob_sizes ipe_blobs __ro_after_init = {
+#ifdef CONFIG_BLK_DEV_INITRD
+	.lbs_superblock = sizeof(struct ipe_sb),
+#endif /* CONFIG_BLK_DEV_INITRD */
 };
 
 static const struct lsm_id ipe_lsmid = {
@@ -15,12 +19,22 @@ static const struct lsm_id ipe_lsmid = {
 	.id = LSM_ID_IPE,
 };
 
+#ifdef CONFIG_BLK_DEV_INITRD
+struct ipe_sb *ipe_sb(const struct super_block *sb)
+{
+	return sb->s_security + ipe_blobs.lbs_superblock;
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 static struct security_hook_list ipe_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(bprm_check_security, ipe_bprm_check_security),
 	LSM_HOOK_INIT(mmap_file, ipe_mmap_file),
 	LSM_HOOK_INIT(file_mprotect, ipe_file_mprotect),
 	LSM_HOOK_INIT(kernel_read_file, ipe_kernel_read_file),
 	LSM_HOOK_INIT(kernel_load_data, ipe_kernel_load_data),
+#ifdef CONFIG_BLK_DEV_INITRD
+	LSM_HOOK_INIT(unpack_initramfs_security, ipe_unpack_initramfs),
+#endif /* CONFIG_BLK_DEV_INITRD */
 };
 
 /**
diff --git a/security/ipe/ipe.h b/security/ipe/ipe.h
index a1c68d0fc2e0..f1e7c3222b6d 100644
--- a/security/ipe/ipe.h
+++ b/security/ipe/ipe.h
@@ -12,5 +12,8 @@
 #define pr_fmt(fmt) "IPE: " fmt
 
 #include <linux/lsm_hooks.h>
+#ifdef CONFIG_BLK_DEV_INITRD
+struct ipe_sb *ipe_sb(const struct super_block *sb);
+#endif /* CONFIG_BLK_DEV_INITRD */
 
 #endif /* _IPE_H */
diff --git a/security/ipe/policy.h b/security/ipe/policy.h
index fb906f41522b..fb48024bb63e 100644
--- a/security/ipe/policy.h
+++ b/security/ipe/policy.h
@@ -30,6 +30,8 @@ enum ipe_action_type {
 #define IPE_ACTION_INVALID __IPE_ACTION_MAX
 
 enum ipe_prop_type {
+	IPE_PROP_BOOT_VERIFIED_FALSE,
+	IPE_PROP_BOOT_VERIFIED_TRUE,
 	__IPE_PROP_MAX
 };
 
diff --git a/security/ipe/policy_parser.c b/security/ipe/policy_parser.c
index 612839b405f4..cce15f0eb645 100644
--- a/security/ipe/policy_parser.c
+++ b/security/ipe/policy_parser.c
@@ -265,6 +265,14 @@ static enum ipe_action_type parse_action(char *t)
 	return match_token(t, action_tokens, args);
 }
 
+static const match_table_t property_tokens = {
+#ifdef CONFIG_BLK_DEV_INITRD
+	{IPE_PROP_BOOT_VERIFIED_FALSE,	"boot_verified=FALSE"},
+	{IPE_PROP_BOOT_VERIFIED_TRUE,	"boot_verified=TRUE"},
+#endif /* CONFIG_BLK_DEV_INITRD */
+	{IPE_PROP_INVALID,		NULL}
+};
+
 /**
  * parse_property - Parse the property type given a token string.
  * @t: Supplies the token string to be parsed.
@@ -277,7 +285,34 @@ static enum ipe_action_type parse_action(char *t)
  */
 static int parse_property(char *t, struct ipe_rule *r)
 {
-	return -EBADMSG;
+	substring_t args[MAX_OPT_ARGS];
+	struct ipe_prop *p = NULL;
+	int rc = 0;
+	int token;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	token = match_token(t, property_tokens, args);
+
+	switch (token) {
+	case IPE_PROP_BOOT_VERIFIED_FALSE:
+	case IPE_PROP_BOOT_VERIFIED_TRUE:
+		p->type = token;
+		break;
+	default:
+		rc = -EBADMSG;
+		break;
+	}
+	if (rc)
+		goto err;
+	list_add_tail(&p->next, &r->props);
+
+	return rc;
+err:
+	kfree(p);
+	return rc;
 }
 
 /**
-- 
2.43.0


  parent reply	other threads:[~2024-01-30 22:37 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-30 22:36 [RFC PATCH v12 00/20] Integrity Policy Enforcement LSM (IPE) Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 01/20] security: add ipe lsm Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 02/20] ipe: add policy parser Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 03/20] ipe: add evaluation loop Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 04/20] ipe: add LSM hooks on execution and kernel read Fan Wu
2024-02-02 14:47   ` kernel test robot
2024-01-30 22:36 ` [RFC PATCH v12 05/20] initramfs|security: Add security hook to initramfs unpack Fan Wu
2024-02-03 22:25   ` [PATCH RFC v12 5/20] " Paul Moore
2024-02-05 21:18     ` Fan Wu
2024-01-30 22:36 ` Fan Wu [this message]
2024-02-03 22:25   ` [PATCH RFC v12 6/20] ipe: introduce 'boot_verified' as a trust provider Paul Moore
2024-02-05 22:39     ` Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 07/20] security: add new securityfs delete function Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 08/20] ipe: add userspace interface Fan Wu
2024-02-03 22:25   ` [PATCH RFC v12 8/20] " Paul Moore
2024-02-05 23:01     ` Fan Wu
2024-02-05 23:10       ` Paul Moore
2024-02-05 23:21         ` Fan Wu
2024-01-30 22:36 ` [RFC PATCH v12 09/20] uapi|audit|ipe: add ipe auditing support Fan Wu
2024-02-03 22:25   ` [PATCH RFC v12 9/20] " Paul Moore
2024-01-30 22:36 ` [RFC PATCH v12 10/20] ipe: add permissive toggle Fan Wu
2024-02-03 22:25   ` [PATCH RFC " Paul Moore
2024-01-30 22:36 ` [RFC PATCH v12 11/20] block|security: add LSM blob to block_device Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 12/20] dm verity: set DM_TARGET_SINGLETON feature flag Fan Wu
2024-02-02 18:51   ` Mike Snitzer
2024-02-03  3:56     ` Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 13/20] dm: add finalize hook to target_type Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 14/20] dm verity: consume root hash digest and signature data via LSM hook Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 15/20] ipe: add support for dm-verity as a trust provider Fan Wu
2024-02-03 22:25   ` [PATCH RFC " Paul Moore
2024-02-05 23:11     ` Fan Wu
2024-02-06 21:53       ` Paul Moore
2024-01-30 22:37 ` [RFC PATCH v12 16/20] fsverity: consume builtin signature via LSM hook Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 17/20] ipe: enable support for fs-verity as a trust provider Fan Wu
2024-02-03 22:25   ` [PATCH RFC " Paul Moore
2024-01-30 22:37 ` [RFC PATCH v12 18/20] scripts: add boot policy generation program Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 19/20] ipe: kunit test for parser Fan Wu
2024-01-30 22:37 ` [RFC PATCH v12 20/20] documentation: add ipe documentation Fan Wu

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=1706654228-17180-7-git-send-email-wufan@linux.microsoft.com \
    --to=wufan@linux.microsoft.com \
    --cc=agk@redhat.com \
    --cc=audit@vger.kernel.org \
    --cc=axboe@kernel.dk \
    --cc=corbet@lwn.net \
    --cc=deven.desai@linux.microsoft.com \
    --cc=dm-devel@lists.linux.dev \
    --cc=ebiggers@kernel.org \
    --cc=eparis@redhat.com \
    --cc=jmorris@namei.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=serge@hallyn.com \
    --cc=snitzer@kernel.org \
    --cc=tytso@mit.edu \
    --cc=zohar@linux.ibm.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.