All of lore.kernel.org
 help / color / mirror / Atom feed
From: deven.desai@linux.microsoft.com
To: corbet@lwn.net, axboe@kernel.dk, agk@redhat.com,
	snitzer@redhat.com, ebiggers@kernel.org, tytso@mit.edu,
	paul@paul-moore.com, eparis@redhat.com, jmorris@namei.org,
	serge@hallyn.com
Cc: jannh@google.com, dm-devel@redhat.com, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-block@vger.kernel.org,
	linux-fscrypt@vger.kernel.org, linux-audit@redhat.com,
	linux-security-module@vger.kernel.org
Subject: [RFC PATCH v7 10/16] fs|dm-verity: add block_dev LSM blob and submit dm-verity data
Date: Wed, 13 Oct 2021 12:06:29 -0700	[thread overview]
Message-ID: <1634151995-16266-11-git-send-email-deven.desai@linux.microsoft.com> (raw)
In-Reply-To: <1634151995-16266-1-git-send-email-deven.desai@linux.microsoft.com>

From: Deven Bowers <deven.desai@linux.microsoft.com>

dm-verity operates on the block_device level. In order to allow IPE to
determine if a file is sourced from a dm-verity volume, and how that
dm-verity volume was created, create an LSM blob with the signature
data and roothash information, allowing IPE to make decisions about
controls to a resource based on dm-verity information.

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

Relevant changes since v5:
  * Change if statement condition in security_bdev_setsecurity to be
    more concise, as suggested by Casey Schaufler and Al Viro

Relevant changes since v6:
  * Squash patch 05/12, 07/12, 09/12 to [10/16]

---
 block/bdev.c                      |  7 ++++
 drivers/md/dm-verity-target.c     | 20 ++++++++-
 drivers/md/dm-verity-verify-sig.c | 16 +++++--
 drivers/md/dm-verity-verify-sig.h | 10 +++--
 include/linux/blk_types.h         |  1 +
 include/linux/device-mapper.h     |  3 ++
 include/linux/lsm_hook_defs.h     |  5 +++
 include/linux/lsm_hooks.h         | 12 ++++++
 include/linux/security.h          | 22 ++++++++++
 security/security.c               | 70 +++++++++++++++++++++++++++++++
 10 files changed, 157 insertions(+), 9 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 485a258b0ab3..4c0d6aaa1f08 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -23,6 +23,7 @@
 #include <linux/pseudo_fs.h>
 #include <linux/uio.h>
 #include <linux/namei.h>
+#include <linux/security.h>
 #include <linux/cleancache.h>
 #include <linux/part_stat.h>
 #include <linux/uaccess.h>
@@ -393,6 +394,11 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
 	if (!ei)
 		return NULL;
 	memset(&ei->bdev, 0, sizeof(ei->bdev));
+
+	if (unlikely(security_bdev_alloc(&ei->bdev))) {
+		kmem_cache_free(bdev_cachep, ei);
+		return NULL;
+	}
 	return &ei->vfs_inode;
 }
 
@@ -402,6 +408,7 @@ static void bdev_free_inode(struct inode *inode)
 
 	free_percpu(bdev->bd_stats);
 	kfree(bdev->bd_meta_info);
+	security_bdev_free(bdev);
 
 	if (!bdev_is_partition(bdev)) {
 		if (bdev->bd_disk && bdev->bd_disk->bdi)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 22a5ac82446a..e62480803e56 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -13,11 +13,14 @@
  * access behavior.
  */
 
+#include "dm-core.h"
 #include "dm-verity.h"
 #include "dm-verity-fec.h"
 #include "dm-verity-verify-sig.h"
+#include "dm-core.h"
 #include <linux/module.h>
 #include <linux/reboot.h>
+#include <linux/security.h>
 
 #define DM_MSG_PREFIX			"verity"
 
@@ -1051,6 +1054,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	sector_t hash_position;
 	char dummy;
 	char *root_hash_digest_to_validate;
+	struct block_device *bdev;
 
 	v = kzalloc(sizeof(struct dm_verity), GFP_KERNEL);
 	if (!v) {
@@ -1084,6 +1088,13 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	}
 	v->version = num;
 
+	bdev = dm_table_get_md(ti->table)->disk->part0;
+	if (!bdev) {
+		ti->error = "Mapped device lookup failed";
+		r = -ENOMEM;
+		goto bad;
+	}
+
 	r = dm_get_device(ti, argv[1], FMODE_READ, &v->data_dev);
 	if (r) {
 		ti->error = "Data device lookup failed";
@@ -1216,7 +1227,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	}
 
 	/* Root hash signature is  a optional parameter*/
-	r = verity_verify_root_hash(root_hash_digest_to_validate,
+	r = verity_verify_root_hash(bdev, root_hash_digest_to_validate,
 				    strlen(root_hash_digest_to_validate),
 				    verify_args.sig,
 				    verify_args.sig_size);
@@ -1289,12 +1300,17 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	ti->per_io_data_size = roundup(ti->per_io_data_size,
 				       __alignof__(struct dm_verity_io));
 
+	r = security_bdev_setsecurity(bdev,
+				      DM_VERITY_ROOTHASH_SEC_NAME,
+				      v->root_digest, v->digest_size);
+	if (r)
+		goto bad;
+
 	verity_verify_sig_opts_cleanup(&verify_args);
 
 	return 0;
 
 bad:
-
 	verity_verify_sig_opts_cleanup(&verify_args);
 	verity_dtr(ti);
 
diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
index db61a1f43ae9..1672a35f292b 100644
--- a/drivers/md/dm-verity-verify-sig.c
+++ b/drivers/md/dm-verity-verify-sig.c
@@ -8,7 +8,10 @@
 #include <linux/device-mapper.h>
 #include <linux/verification.h>
 #include <keys/user-type.h>
+#include <linux/security.h>
+#include <linux/list.h>
 #include <linux/module.h>
+#include "dm-core.h"
 #include "dm-verity.h"
 #include "dm-verity-verify-sig.h"
 
@@ -97,14 +100,17 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
  * verify_verify_roothash - Verify the root hash of the verity hash device
  *			     using builtin trusted keys.
  *
+ * @bdev: block_device representing the device-mapper created block device.
+ *	Used by the security hook, to set information about the block_device.
  * @root_hash: For verity, the roothash/data to be verified.
  * @root_hash_len: Size of the roothash/data to be verified.
  * @sig_data: The trusted signature that verifies the roothash/data.
  * @sig_len: Size of the signature.
  *
  */
-int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
-			    const void *sig_data, size_t sig_len)
+int verity_verify_root_hash(struct block_device *bdev, const void *root_hash,
+			    size_t root_hash_len, const void *sig_data,
+			    size_t sig_len)
 {
 	int ret;
 
@@ -126,8 +132,12 @@ int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
 				NULL,
 #endif
 				VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
+	if (ret)
+		return ret;
 
-	return ret;
+	return security_bdev_setsecurity(bdev,
+					 DM_VERITY_SIGNATURE_SEC_NAME,
+					 sig_data, sig_len);
 }
 
 void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts)
diff --git a/drivers/md/dm-verity-verify-sig.h b/drivers/md/dm-verity-verify-sig.h
index 3987c7141f79..31692fff92e4 100644
--- a/drivers/md/dm-verity-verify-sig.h
+++ b/drivers/md/dm-verity-verify-sig.h
@@ -20,8 +20,9 @@ struct dm_verity_sig_opts {
 
 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 2
 
-int verity_verify_root_hash(const void *data, size_t data_len,
-			    const void *sig_data, size_t sig_len);
+int verity_verify_root_hash(struct block_device *bdev, const void *data,
+			    size_t data_len, const void *sig_data,
+			    size_t sig_len);
 bool verity_verify_is_sig_opt_arg(const char *arg_name);
 
 int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
@@ -34,8 +35,9 @@ void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts);
 
 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0
 
-static inline int verity_verify_root_hash(const void *data, size_t data_len,
-					  const void *sig_data, size_t sig_len)
+int verity_verify_root_hash(struct block_device *bdev, const void *data,
+			    size_t data_len, const void *sig_data,
+			    size_t sig_len)
 {
 	return 0;
 }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index be622b5a21ed..58def70aa653 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -49,6 +49,7 @@ struct block_device {
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	bool			bd_make_it_fail;
 #endif
+	void			*security;
 } __randomize_layout;
 
 #define bdev_whole(_bdev) \
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 114553b487ef..0f5bdcfcf337 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -665,4 +665,7 @@ static inline unsigned long to_bytes(sector_t n)
 	return (n << SECTOR_SHIFT);
 }
 
+#define DM_VERITY_SIGNATURE_SEC_NAME DM_NAME	".verity-sig"
+#define DM_VERITY_ROOTHASH_SEC_NAME DM_NAME	".verity-rh"
+
 #endif	/* _LINUX_DEVICE_MAPPER_H */
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 2adeea44c0d5..b148a01b2cef 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -402,3 +402,8 @@ LSM_HOOK(void, LSM_RET_VOID, perf_event_free, struct perf_event *event)
 LSM_HOOK(int, 0, perf_event_read, struct perf_event *event)
 LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
 #endif /* CONFIG_PERF_EVENTS */
+
+LSM_HOOK(int, 0, bdev_alloc_security, struct block_device *bdev)
+LSM_HOOK(void, LSM_RET_VOID, bdev_free_security, struct block_device *bdev)
+LSM_HOOK(int, 0, bdev_setsecurity, struct block_device *bdev, const char *name,
+	 const void *value, size_t size)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 5c4c5c0602cb..43d357e6ab47 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1545,6 +1545,17 @@
  *
  *     @what: kernel feature being accessed
  *
+ * @bdev_alloc_security:
+ *	Initialize the security field inside a block_device structure.
+ *
+ * @bdev_free_security:
+ *	Cleanup the security information stored inside a block_device structure.
+ *
+ * @bdev_setsecurity:
+ *	Set a security property associated with @name for @bdev with
+ *	value @value. @size indicates the size of @value in bytes.
+ *	If a @name is not implemented, return -ENOSYS.
+ *
  * Security hooks for perf events
  *
  * @perf_event_open:
@@ -1592,6 +1603,7 @@ struct lsm_blob_sizes {
 	int	lbs_ipc;
 	int	lbs_msg_msg;
 	int	lbs_task;
+	int	lbs_bdev;
 };
 
 /*
diff --git a/include/linux/security.h b/include/linux/security.h
index 5b7288521300..98af3f645cb6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -472,6 +472,11 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 int security_locked_down(enum lockdown_reason what);
+int security_bdev_alloc(struct block_device *bdev);
+void security_bdev_free(struct block_device *bdev);
+int security_bdev_setsecurity(struct block_device *bdev,
+			      const char *name, const void *value,
+			      size_t size);
 #else /* CONFIG_SECURITY */
 
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -1348,6 +1353,23 @@ static inline int security_locked_down(enum lockdown_reason what)
 {
 	return 0;
 }
+
+static inline int security_bdev_alloc(struct block_device *bdev)
+{
+	return 0;
+}
+
+static inline void security_bdev_free(struct block_device *bdev)
+{
+}
+
+static inline int security_bdev_setsecurity(struct block_device *bdev,
+					    const char *name,
+					    const void *value, size_t size)
+{
+	return 0;
+}
+
 #endif	/* CONFIG_SECURITY */
 
 #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
diff --git a/security/security.c b/security/security.c
index 9ffa9e9c5c55..d7ac9f01500b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/msg.h>
 #include <net/flow.h>
+#include <linux/fs.h>
 
 #define MAX_LSM_EVM_XATTR	2
 
@@ -206,6 +207,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
 	lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
 	lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
 	lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
+	lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
 }
 
 /* Prepare LSM for initialization. */
@@ -342,6 +344,7 @@ static void __init ordered_lsm_init(void)
 	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
 	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
 	init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
+	init_debug("bdev blob size       = %d\n", blob_sizes.lbs_bdev);
 
 	/*
 	 * Create any kmem_caches needed for blobs
@@ -659,6 +662,28 @@ static int lsm_msg_msg_alloc(struct msg_msg *mp)
 	return 0;
 }
 
+/**
+ * lsm_bdev_alloc - allocate a composite block_device blob
+ * @bdev: the block_device that needs a blob
+ *
+ * Allocate the block_device blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bdev_alloc(struct block_device *bdev)
+{
+	if (blob_sizes.lbs_bdev == 0) {
+		bdev->security = NULL;
+		return 0;
+	}
+
+	bdev->security = kzalloc(blob_sizes.lbs_bdev, GFP_KERNEL);
+	if (!bdev->security)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /**
  * lsm_early_task - during initialization allocate a composite task blob
  * @task: the task that needs a blob
@@ -2599,6 +2624,51 @@ int security_locked_down(enum lockdown_reason what)
 }
 EXPORT_SYMBOL(security_locked_down);
 
+int security_bdev_alloc(struct block_device *bdev)
+{
+	int rc = 0;
+
+	rc = lsm_bdev_alloc(bdev);
+	if (unlikely(rc))
+		return rc;
+
+	rc = call_int_hook(bdev_alloc_security, 0, bdev);
+	if (unlikely(rc))
+		security_bdev_free(bdev);
+
+	return 0;
+}
+EXPORT_SYMBOL(security_bdev_alloc);
+
+void security_bdev_free(struct block_device *bdev)
+{
+	if (!bdev->security)
+		return;
+
+	call_void_hook(bdev_free_security, bdev);
+
+	kfree(bdev->security);
+	bdev->security = NULL;
+}
+EXPORT_SYMBOL(security_bdev_free);
+
+int security_bdev_setsecurity(struct block_device *bdev,
+			      const char *name, const void *value,
+			      size_t size)
+{
+	int rc = 0;
+	struct security_hook_list *p;
+
+	hlist_for_each_entry(p, &security_hook_heads.bdev_setsecurity, list) {
+		rc = p->hook.bdev_setsecurity(bdev, name, value, size);
+		if (rc && rc != -ENOSYS)
+			return rc;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(security_bdev_setsecurity);
+
 #ifdef CONFIG_PERF_EVENTS
 int security_perf_event_open(struct perf_event_attr *attr, int type)
 {
-- 
2.33.0


WARNING: multiple messages have this Message-ID (diff)
From: deven.desai@linux.microsoft.com
To: corbet@lwn.net, axboe@kernel.dk, agk@redhat.com,
	snitzer@redhat.com, ebiggers@kernel.org, tytso@mit.edu,
	paul@paul-moore.com, eparis@redhat.com, jmorris@namei.org,
	serge@hallyn.com
Cc: linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org,
	jannh@google.com, linux-fscrypt@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-block@vger.kernel.org,
	dm-devel@redhat.com, linux-audit@redhat.com
Subject: [dm-devel] [RFC PATCH v7 10/16] fs|dm-verity: add block_dev LSM blob and submit dm-verity data
Date: Wed, 13 Oct 2021 12:06:29 -0700	[thread overview]
Message-ID: <1634151995-16266-11-git-send-email-deven.desai@linux.microsoft.com> (raw)
In-Reply-To: <1634151995-16266-1-git-send-email-deven.desai@linux.microsoft.com>

From: Deven Bowers <deven.desai@linux.microsoft.com>

dm-verity operates on the block_device level. In order to allow IPE to
determine if a file is sourced from a dm-verity volume, and how that
dm-verity volume was created, create an LSM blob with the signature
data and roothash information, allowing IPE to make decisions about
controls to a resource based on dm-verity information.

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

Relevant changes since v5:
  * Change if statement condition in security_bdev_setsecurity to be
    more concise, as suggested by Casey Schaufler and Al Viro

Relevant changes since v6:
  * Squash patch 05/12, 07/12, 09/12 to [10/16]

---
 block/bdev.c                      |  7 ++++
 drivers/md/dm-verity-target.c     | 20 ++++++++-
 drivers/md/dm-verity-verify-sig.c | 16 +++++--
 drivers/md/dm-verity-verify-sig.h | 10 +++--
 include/linux/blk_types.h         |  1 +
 include/linux/device-mapper.h     |  3 ++
 include/linux/lsm_hook_defs.h     |  5 +++
 include/linux/lsm_hooks.h         | 12 ++++++
 include/linux/security.h          | 22 ++++++++++
 security/security.c               | 70 +++++++++++++++++++++++++++++++
 10 files changed, 157 insertions(+), 9 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 485a258b0ab3..4c0d6aaa1f08 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -23,6 +23,7 @@
 #include <linux/pseudo_fs.h>
 #include <linux/uio.h>
 #include <linux/namei.h>
+#include <linux/security.h>
 #include <linux/cleancache.h>
 #include <linux/part_stat.h>
 #include <linux/uaccess.h>
@@ -393,6 +394,11 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
 	if (!ei)
 		return NULL;
 	memset(&ei->bdev, 0, sizeof(ei->bdev));
+
+	if (unlikely(security_bdev_alloc(&ei->bdev))) {
+		kmem_cache_free(bdev_cachep, ei);
+		return NULL;
+	}
 	return &ei->vfs_inode;
 }
 
@@ -402,6 +408,7 @@ static void bdev_free_inode(struct inode *inode)
 
 	free_percpu(bdev->bd_stats);
 	kfree(bdev->bd_meta_info);
+	security_bdev_free(bdev);
 
 	if (!bdev_is_partition(bdev)) {
 		if (bdev->bd_disk && bdev->bd_disk->bdi)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 22a5ac82446a..e62480803e56 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -13,11 +13,14 @@
  * access behavior.
  */
 
+#include "dm-core.h"
 #include "dm-verity.h"
 #include "dm-verity-fec.h"
 #include "dm-verity-verify-sig.h"
+#include "dm-core.h"
 #include <linux/module.h>
 #include <linux/reboot.h>
+#include <linux/security.h>
 
 #define DM_MSG_PREFIX			"verity"
 
@@ -1051,6 +1054,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	sector_t hash_position;
 	char dummy;
 	char *root_hash_digest_to_validate;
+	struct block_device *bdev;
 
 	v = kzalloc(sizeof(struct dm_verity), GFP_KERNEL);
 	if (!v) {
@@ -1084,6 +1088,13 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	}
 	v->version = num;
 
+	bdev = dm_table_get_md(ti->table)->disk->part0;
+	if (!bdev) {
+		ti->error = "Mapped device lookup failed";
+		r = -ENOMEM;
+		goto bad;
+	}
+
 	r = dm_get_device(ti, argv[1], FMODE_READ, &v->data_dev);
 	if (r) {
 		ti->error = "Data device lookup failed";
@@ -1216,7 +1227,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	}
 
 	/* Root hash signature is  a optional parameter*/
-	r = verity_verify_root_hash(root_hash_digest_to_validate,
+	r = verity_verify_root_hash(bdev, root_hash_digest_to_validate,
 				    strlen(root_hash_digest_to_validate),
 				    verify_args.sig,
 				    verify_args.sig_size);
@@ -1289,12 +1300,17 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	ti->per_io_data_size = roundup(ti->per_io_data_size,
 				       __alignof__(struct dm_verity_io));
 
+	r = security_bdev_setsecurity(bdev,
+				      DM_VERITY_ROOTHASH_SEC_NAME,
+				      v->root_digest, v->digest_size);
+	if (r)
+		goto bad;
+
 	verity_verify_sig_opts_cleanup(&verify_args);
 
 	return 0;
 
 bad:
-
 	verity_verify_sig_opts_cleanup(&verify_args);
 	verity_dtr(ti);
 
diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
index db61a1f43ae9..1672a35f292b 100644
--- a/drivers/md/dm-verity-verify-sig.c
+++ b/drivers/md/dm-verity-verify-sig.c
@@ -8,7 +8,10 @@
 #include <linux/device-mapper.h>
 #include <linux/verification.h>
 #include <keys/user-type.h>
+#include <linux/security.h>
+#include <linux/list.h>
 #include <linux/module.h>
+#include "dm-core.h"
 #include "dm-verity.h"
 #include "dm-verity-verify-sig.h"
 
@@ -97,14 +100,17 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
  * verify_verify_roothash - Verify the root hash of the verity hash device
  *			     using builtin trusted keys.
  *
+ * @bdev: block_device representing the device-mapper created block device.
+ *	Used by the security hook, to set information about the block_device.
  * @root_hash: For verity, the roothash/data to be verified.
  * @root_hash_len: Size of the roothash/data to be verified.
  * @sig_data: The trusted signature that verifies the roothash/data.
  * @sig_len: Size of the signature.
  *
  */
-int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
-			    const void *sig_data, size_t sig_len)
+int verity_verify_root_hash(struct block_device *bdev, const void *root_hash,
+			    size_t root_hash_len, const void *sig_data,
+			    size_t sig_len)
 {
 	int ret;
 
@@ -126,8 +132,12 @@ int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
 				NULL,
 #endif
 				VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
+	if (ret)
+		return ret;
 
-	return ret;
+	return security_bdev_setsecurity(bdev,
+					 DM_VERITY_SIGNATURE_SEC_NAME,
+					 sig_data, sig_len);
 }
 
 void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts)
diff --git a/drivers/md/dm-verity-verify-sig.h b/drivers/md/dm-verity-verify-sig.h
index 3987c7141f79..31692fff92e4 100644
--- a/drivers/md/dm-verity-verify-sig.h
+++ b/drivers/md/dm-verity-verify-sig.h
@@ -20,8 +20,9 @@ struct dm_verity_sig_opts {
 
 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 2
 
-int verity_verify_root_hash(const void *data, size_t data_len,
-			    const void *sig_data, size_t sig_len);
+int verity_verify_root_hash(struct block_device *bdev, const void *data,
+			    size_t data_len, const void *sig_data,
+			    size_t sig_len);
 bool verity_verify_is_sig_opt_arg(const char *arg_name);
 
 int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
@@ -34,8 +35,9 @@ void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts);
 
 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0
 
-static inline int verity_verify_root_hash(const void *data, size_t data_len,
-					  const void *sig_data, size_t sig_len)
+int verity_verify_root_hash(struct block_device *bdev, const void *data,
+			    size_t data_len, const void *sig_data,
+			    size_t sig_len)
 {
 	return 0;
 }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index be622b5a21ed..58def70aa653 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -49,6 +49,7 @@ struct block_device {
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	bool			bd_make_it_fail;
 #endif
+	void			*security;
 } __randomize_layout;
 
 #define bdev_whole(_bdev) \
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 114553b487ef..0f5bdcfcf337 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -665,4 +665,7 @@ static inline unsigned long to_bytes(sector_t n)
 	return (n << SECTOR_SHIFT);
 }
 
+#define DM_VERITY_SIGNATURE_SEC_NAME DM_NAME	".verity-sig"
+#define DM_VERITY_ROOTHASH_SEC_NAME DM_NAME	".verity-rh"
+
 #endif	/* _LINUX_DEVICE_MAPPER_H */
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 2adeea44c0d5..b148a01b2cef 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -402,3 +402,8 @@ LSM_HOOK(void, LSM_RET_VOID, perf_event_free, struct perf_event *event)
 LSM_HOOK(int, 0, perf_event_read, struct perf_event *event)
 LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
 #endif /* CONFIG_PERF_EVENTS */
+
+LSM_HOOK(int, 0, bdev_alloc_security, struct block_device *bdev)
+LSM_HOOK(void, LSM_RET_VOID, bdev_free_security, struct block_device *bdev)
+LSM_HOOK(int, 0, bdev_setsecurity, struct block_device *bdev, const char *name,
+	 const void *value, size_t size)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 5c4c5c0602cb..43d357e6ab47 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1545,6 +1545,17 @@
  *
  *     @what: kernel feature being accessed
  *
+ * @bdev_alloc_security:
+ *	Initialize the security field inside a block_device structure.
+ *
+ * @bdev_free_security:
+ *	Cleanup the security information stored inside a block_device structure.
+ *
+ * @bdev_setsecurity:
+ *	Set a security property associated with @name for @bdev with
+ *	value @value. @size indicates the size of @value in bytes.
+ *	If a @name is not implemented, return -ENOSYS.
+ *
  * Security hooks for perf events
  *
  * @perf_event_open:
@@ -1592,6 +1603,7 @@ struct lsm_blob_sizes {
 	int	lbs_ipc;
 	int	lbs_msg_msg;
 	int	lbs_task;
+	int	lbs_bdev;
 };
 
 /*
diff --git a/include/linux/security.h b/include/linux/security.h
index 5b7288521300..98af3f645cb6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -472,6 +472,11 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 int security_locked_down(enum lockdown_reason what);
+int security_bdev_alloc(struct block_device *bdev);
+void security_bdev_free(struct block_device *bdev);
+int security_bdev_setsecurity(struct block_device *bdev,
+			      const char *name, const void *value,
+			      size_t size);
 #else /* CONFIG_SECURITY */
 
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -1348,6 +1353,23 @@ static inline int security_locked_down(enum lockdown_reason what)
 {
 	return 0;
 }
+
+static inline int security_bdev_alloc(struct block_device *bdev)
+{
+	return 0;
+}
+
+static inline void security_bdev_free(struct block_device *bdev)
+{
+}
+
+static inline int security_bdev_setsecurity(struct block_device *bdev,
+					    const char *name,
+					    const void *value, size_t size)
+{
+	return 0;
+}
+
 #endif	/* CONFIG_SECURITY */
 
 #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
diff --git a/security/security.c b/security/security.c
index 9ffa9e9c5c55..d7ac9f01500b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/msg.h>
 #include <net/flow.h>
+#include <linux/fs.h>
 
 #define MAX_LSM_EVM_XATTR	2
 
@@ -206,6 +207,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
 	lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
 	lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
 	lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
+	lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
 }
 
 /* Prepare LSM for initialization. */
@@ -342,6 +344,7 @@ static void __init ordered_lsm_init(void)
 	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
 	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
 	init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
+	init_debug("bdev blob size       = %d\n", blob_sizes.lbs_bdev);
 
 	/*
 	 * Create any kmem_caches needed for blobs
@@ -659,6 +662,28 @@ static int lsm_msg_msg_alloc(struct msg_msg *mp)
 	return 0;
 }
 
+/**
+ * lsm_bdev_alloc - allocate a composite block_device blob
+ * @bdev: the block_device that needs a blob
+ *
+ * Allocate the block_device blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bdev_alloc(struct block_device *bdev)
+{
+	if (blob_sizes.lbs_bdev == 0) {
+		bdev->security = NULL;
+		return 0;
+	}
+
+	bdev->security = kzalloc(blob_sizes.lbs_bdev, GFP_KERNEL);
+	if (!bdev->security)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /**
  * lsm_early_task - during initialization allocate a composite task blob
  * @task: the task that needs a blob
@@ -2599,6 +2624,51 @@ int security_locked_down(enum lockdown_reason what)
 }
 EXPORT_SYMBOL(security_locked_down);
 
+int security_bdev_alloc(struct block_device *bdev)
+{
+	int rc = 0;
+
+	rc = lsm_bdev_alloc(bdev);
+	if (unlikely(rc))
+		return rc;
+
+	rc = call_int_hook(bdev_alloc_security, 0, bdev);
+	if (unlikely(rc))
+		security_bdev_free(bdev);
+
+	return 0;
+}
+EXPORT_SYMBOL(security_bdev_alloc);
+
+void security_bdev_free(struct block_device *bdev)
+{
+	if (!bdev->security)
+		return;
+
+	call_void_hook(bdev_free_security, bdev);
+
+	kfree(bdev->security);
+	bdev->security = NULL;
+}
+EXPORT_SYMBOL(security_bdev_free);
+
+int security_bdev_setsecurity(struct block_device *bdev,
+			      const char *name, const void *value,
+			      size_t size)
+{
+	int rc = 0;
+	struct security_hook_list *p;
+
+	hlist_for_each_entry(p, &security_hook_heads.bdev_setsecurity, list) {
+		rc = p->hook.bdev_setsecurity(bdev, name, value, size);
+		if (rc && rc != -ENOSYS)
+			return rc;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(security_bdev_setsecurity);
+
 #ifdef CONFIG_PERF_EVENTS
 int security_perf_event_open(struct perf_event_attr *attr, int type)
 {
-- 
2.33.0

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


WARNING: multiple messages have this Message-ID (diff)
From: deven.desai@linux.microsoft.com
To: corbet@lwn.net, axboe@kernel.dk, agk@redhat.com,
	snitzer@redhat.com, ebiggers@kernel.org, tytso@mit.edu,
	paul@paul-moore.com, eparis@redhat.com, jmorris@namei.org,
	serge@hallyn.com
Cc: linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org,
	jannh@google.com, linux-fscrypt@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-block@vger.kernel.org,
	dm-devel@redhat.com, linux-audit@redhat.com
Subject: [RFC PATCH v7 10/16] fs|dm-verity: add block_dev LSM blob and submit dm-verity data
Date: Wed, 13 Oct 2021 12:06:29 -0700	[thread overview]
Message-ID: <1634151995-16266-11-git-send-email-deven.desai@linux.microsoft.com> (raw)
In-Reply-To: <1634151995-16266-1-git-send-email-deven.desai@linux.microsoft.com>

From: Deven Bowers <deven.desai@linux.microsoft.com>

dm-verity operates on the block_device level. In order to allow IPE to
determine if a file is sourced from a dm-verity volume, and how that
dm-verity volume was created, create an LSM blob with the signature
data and roothash information, allowing IPE to make decisions about
controls to a resource based on dm-verity information.

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

Relevant changes since v5:
  * Change if statement condition in security_bdev_setsecurity to be
    more concise, as suggested by Casey Schaufler and Al Viro

Relevant changes since v6:
  * Squash patch 05/12, 07/12, 09/12 to [10/16]

---
 block/bdev.c                      |  7 ++++
 drivers/md/dm-verity-target.c     | 20 ++++++++-
 drivers/md/dm-verity-verify-sig.c | 16 +++++--
 drivers/md/dm-verity-verify-sig.h | 10 +++--
 include/linux/blk_types.h         |  1 +
 include/linux/device-mapper.h     |  3 ++
 include/linux/lsm_hook_defs.h     |  5 +++
 include/linux/lsm_hooks.h         | 12 ++++++
 include/linux/security.h          | 22 ++++++++++
 security/security.c               | 70 +++++++++++++++++++++++++++++++
 10 files changed, 157 insertions(+), 9 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index 485a258b0ab3..4c0d6aaa1f08 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -23,6 +23,7 @@
 #include <linux/pseudo_fs.h>
 #include <linux/uio.h>
 #include <linux/namei.h>
+#include <linux/security.h>
 #include <linux/cleancache.h>
 #include <linux/part_stat.h>
 #include <linux/uaccess.h>
@@ -393,6 +394,11 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
 	if (!ei)
 		return NULL;
 	memset(&ei->bdev, 0, sizeof(ei->bdev));
+
+	if (unlikely(security_bdev_alloc(&ei->bdev))) {
+		kmem_cache_free(bdev_cachep, ei);
+		return NULL;
+	}
 	return &ei->vfs_inode;
 }
 
@@ -402,6 +408,7 @@ static void bdev_free_inode(struct inode *inode)
 
 	free_percpu(bdev->bd_stats);
 	kfree(bdev->bd_meta_info);
+	security_bdev_free(bdev);
 
 	if (!bdev_is_partition(bdev)) {
 		if (bdev->bd_disk && bdev->bd_disk->bdi)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 22a5ac82446a..e62480803e56 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -13,11 +13,14 @@
  * access behavior.
  */
 
+#include "dm-core.h"
 #include "dm-verity.h"
 #include "dm-verity-fec.h"
 #include "dm-verity-verify-sig.h"
+#include "dm-core.h"
 #include <linux/module.h>
 #include <linux/reboot.h>
+#include <linux/security.h>
 
 #define DM_MSG_PREFIX			"verity"
 
@@ -1051,6 +1054,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	sector_t hash_position;
 	char dummy;
 	char *root_hash_digest_to_validate;
+	struct block_device *bdev;
 
 	v = kzalloc(sizeof(struct dm_verity), GFP_KERNEL);
 	if (!v) {
@@ -1084,6 +1088,13 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	}
 	v->version = num;
 
+	bdev = dm_table_get_md(ti->table)->disk->part0;
+	if (!bdev) {
+		ti->error = "Mapped device lookup failed";
+		r = -ENOMEM;
+		goto bad;
+	}
+
 	r = dm_get_device(ti, argv[1], FMODE_READ, &v->data_dev);
 	if (r) {
 		ti->error = "Data device lookup failed";
@@ -1216,7 +1227,7 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	}
 
 	/* Root hash signature is  a optional parameter*/
-	r = verity_verify_root_hash(root_hash_digest_to_validate,
+	r = verity_verify_root_hash(bdev, root_hash_digest_to_validate,
 				    strlen(root_hash_digest_to_validate),
 				    verify_args.sig,
 				    verify_args.sig_size);
@@ -1289,12 +1300,17 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 	ti->per_io_data_size = roundup(ti->per_io_data_size,
 				       __alignof__(struct dm_verity_io));
 
+	r = security_bdev_setsecurity(bdev,
+				      DM_VERITY_ROOTHASH_SEC_NAME,
+				      v->root_digest, v->digest_size);
+	if (r)
+		goto bad;
+
 	verity_verify_sig_opts_cleanup(&verify_args);
 
 	return 0;
 
 bad:
-
 	verity_verify_sig_opts_cleanup(&verify_args);
 	verity_dtr(ti);
 
diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c
index db61a1f43ae9..1672a35f292b 100644
--- a/drivers/md/dm-verity-verify-sig.c
+++ b/drivers/md/dm-verity-verify-sig.c
@@ -8,7 +8,10 @@
 #include <linux/device-mapper.h>
 #include <linux/verification.h>
 #include <keys/user-type.h>
+#include <linux/security.h>
+#include <linux/list.h>
 #include <linux/module.h>
+#include "dm-core.h"
 #include "dm-verity.h"
 #include "dm-verity-verify-sig.h"
 
@@ -97,14 +100,17 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
  * verify_verify_roothash - Verify the root hash of the verity hash device
  *			     using builtin trusted keys.
  *
+ * @bdev: block_device representing the device-mapper created block device.
+ *	Used by the security hook, to set information about the block_device.
  * @root_hash: For verity, the roothash/data to be verified.
  * @root_hash_len: Size of the roothash/data to be verified.
  * @sig_data: The trusted signature that verifies the roothash/data.
  * @sig_len: Size of the signature.
  *
  */
-int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
-			    const void *sig_data, size_t sig_len)
+int verity_verify_root_hash(struct block_device *bdev, const void *root_hash,
+			    size_t root_hash_len, const void *sig_data,
+			    size_t sig_len)
 {
 	int ret;
 
@@ -126,8 +132,12 @@ int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
 				NULL,
 #endif
 				VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
+	if (ret)
+		return ret;
 
-	return ret;
+	return security_bdev_setsecurity(bdev,
+					 DM_VERITY_SIGNATURE_SEC_NAME,
+					 sig_data, sig_len);
 }
 
 void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts)
diff --git a/drivers/md/dm-verity-verify-sig.h b/drivers/md/dm-verity-verify-sig.h
index 3987c7141f79..31692fff92e4 100644
--- a/drivers/md/dm-verity-verify-sig.h
+++ b/drivers/md/dm-verity-verify-sig.h
@@ -20,8 +20,9 @@ struct dm_verity_sig_opts {
 
 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 2
 
-int verity_verify_root_hash(const void *data, size_t data_len,
-			    const void *sig_data, size_t sig_len);
+int verity_verify_root_hash(struct block_device *bdev, const void *data,
+			    size_t data_len, const void *sig_data,
+			    size_t sig_len);
 bool verity_verify_is_sig_opt_arg(const char *arg_name);
 
 int verity_verify_sig_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
@@ -34,8 +35,9 @@ void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts);
 
 #define DM_VERITY_ROOT_HASH_VERIFICATION_OPTS 0
 
-static inline int verity_verify_root_hash(const void *data, size_t data_len,
-					  const void *sig_data, size_t sig_len)
+int verity_verify_root_hash(struct block_device *bdev, const void *data,
+			    size_t data_len, const void *sig_data,
+			    size_t sig_len)
 {
 	return 0;
 }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index be622b5a21ed..58def70aa653 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -49,6 +49,7 @@ struct block_device {
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	bool			bd_make_it_fail;
 #endif
+	void			*security;
 } __randomize_layout;
 
 #define bdev_whole(_bdev) \
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 114553b487ef..0f5bdcfcf337 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -665,4 +665,7 @@ static inline unsigned long to_bytes(sector_t n)
 	return (n << SECTOR_SHIFT);
 }
 
+#define DM_VERITY_SIGNATURE_SEC_NAME DM_NAME	".verity-sig"
+#define DM_VERITY_ROOTHASH_SEC_NAME DM_NAME	".verity-rh"
+
 #endif	/* _LINUX_DEVICE_MAPPER_H */
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 2adeea44c0d5..b148a01b2cef 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -402,3 +402,8 @@ LSM_HOOK(void, LSM_RET_VOID, perf_event_free, struct perf_event *event)
 LSM_HOOK(int, 0, perf_event_read, struct perf_event *event)
 LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
 #endif /* CONFIG_PERF_EVENTS */
+
+LSM_HOOK(int, 0, bdev_alloc_security, struct block_device *bdev)
+LSM_HOOK(void, LSM_RET_VOID, bdev_free_security, struct block_device *bdev)
+LSM_HOOK(int, 0, bdev_setsecurity, struct block_device *bdev, const char *name,
+	 const void *value, size_t size)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 5c4c5c0602cb..43d357e6ab47 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1545,6 +1545,17 @@
  *
  *     @what: kernel feature being accessed
  *
+ * @bdev_alloc_security:
+ *	Initialize the security field inside a block_device structure.
+ *
+ * @bdev_free_security:
+ *	Cleanup the security information stored inside a block_device structure.
+ *
+ * @bdev_setsecurity:
+ *	Set a security property associated with @name for @bdev with
+ *	value @value. @size indicates the size of @value in bytes.
+ *	If a @name is not implemented, return -ENOSYS.
+ *
  * Security hooks for perf events
  *
  * @perf_event_open:
@@ -1592,6 +1603,7 @@ struct lsm_blob_sizes {
 	int	lbs_ipc;
 	int	lbs_msg_msg;
 	int	lbs_task;
+	int	lbs_bdev;
 };
 
 /*
diff --git a/include/linux/security.h b/include/linux/security.h
index 5b7288521300..98af3f645cb6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -472,6 +472,11 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 int security_locked_down(enum lockdown_reason what);
+int security_bdev_alloc(struct block_device *bdev);
+void security_bdev_free(struct block_device *bdev);
+int security_bdev_setsecurity(struct block_device *bdev,
+			      const char *name, const void *value,
+			      size_t size);
 #else /* CONFIG_SECURITY */
 
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -1348,6 +1353,23 @@ static inline int security_locked_down(enum lockdown_reason what)
 {
 	return 0;
 }
+
+static inline int security_bdev_alloc(struct block_device *bdev)
+{
+	return 0;
+}
+
+static inline void security_bdev_free(struct block_device *bdev)
+{
+}
+
+static inline int security_bdev_setsecurity(struct block_device *bdev,
+					    const char *name,
+					    const void *value, size_t size)
+{
+	return 0;
+}
+
 #endif	/* CONFIG_SECURITY */
 
 #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
diff --git a/security/security.c b/security/security.c
index 9ffa9e9c5c55..d7ac9f01500b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/msg.h>
 #include <net/flow.h>
+#include <linux/fs.h>
 
 #define MAX_LSM_EVM_XATTR	2
 
@@ -206,6 +207,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
 	lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
 	lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
 	lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
+	lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
 }
 
 /* Prepare LSM for initialization. */
@@ -342,6 +344,7 @@ static void __init ordered_lsm_init(void)
 	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
 	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
 	init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
+	init_debug("bdev blob size       = %d\n", blob_sizes.lbs_bdev);
 
 	/*
 	 * Create any kmem_caches needed for blobs
@@ -659,6 +662,28 @@ static int lsm_msg_msg_alloc(struct msg_msg *mp)
 	return 0;
 }
 
+/**
+ * lsm_bdev_alloc - allocate a composite block_device blob
+ * @bdev: the block_device that needs a blob
+ *
+ * Allocate the block_device blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bdev_alloc(struct block_device *bdev)
+{
+	if (blob_sizes.lbs_bdev == 0) {
+		bdev->security = NULL;
+		return 0;
+	}
+
+	bdev->security = kzalloc(blob_sizes.lbs_bdev, GFP_KERNEL);
+	if (!bdev->security)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /**
  * lsm_early_task - during initialization allocate a composite task blob
  * @task: the task that needs a blob
@@ -2599,6 +2624,51 @@ int security_locked_down(enum lockdown_reason what)
 }
 EXPORT_SYMBOL(security_locked_down);
 
+int security_bdev_alloc(struct block_device *bdev)
+{
+	int rc = 0;
+
+	rc = lsm_bdev_alloc(bdev);
+	if (unlikely(rc))
+		return rc;
+
+	rc = call_int_hook(bdev_alloc_security, 0, bdev);
+	if (unlikely(rc))
+		security_bdev_free(bdev);
+
+	return 0;
+}
+EXPORT_SYMBOL(security_bdev_alloc);
+
+void security_bdev_free(struct block_device *bdev)
+{
+	if (!bdev->security)
+		return;
+
+	call_void_hook(bdev_free_security, bdev);
+
+	kfree(bdev->security);
+	bdev->security = NULL;
+}
+EXPORT_SYMBOL(security_bdev_free);
+
+int security_bdev_setsecurity(struct block_device *bdev,
+			      const char *name, const void *value,
+			      size_t size)
+{
+	int rc = 0;
+	struct security_hook_list *p;
+
+	hlist_for_each_entry(p, &security_hook_heads.bdev_setsecurity, list) {
+		rc = p->hook.bdev_setsecurity(bdev, name, value, size);
+		if (rc && rc != -ENOSYS)
+			return rc;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(security_bdev_setsecurity);
+
 #ifdef CONFIG_PERF_EVENTS
 int security_perf_event_open(struct perf_event_attr *attr, int type)
 {
-- 
2.33.0

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit


  parent reply	other threads:[~2021-10-13 19:06 UTC|newest]

Thread overview: 193+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-13 19:06 [RFC PATCH v7 00/16] Integrity Policy Enforcement (IPE) deven.desai
2021-10-13 19:06 ` deven.desai
2021-10-13 19:06 ` [dm-devel] " deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 01/16] security: add ipe lsm & initial context creation deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-27  4:10   ` kernel test robot
2021-10-13 19:06 ` [RFC PATCH v7 02/16] ipe: add policy parser deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-27  5:58   ` kernel test robot
2021-10-13 19:06 ` [RFC PATCH v7 03/16] ipe: add evaluation loop deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-27  8:17   ` kernel test robot
2021-10-13 19:06 ` [RFC PATCH v7 04/16] ipe: add userspace interface deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-11-03  9:42   ` Roberto Sassu
2021-11-03  9:42     ` Roberto Sassu
2021-11-03  9:42     ` [dm-devel] " Roberto Sassu
2021-11-04 16:50     ` Deven Bowers
2021-11-04 16:50       ` Deven Bowers
2021-11-04 16:50       ` [dm-devel] " Deven Bowers
2021-10-13 19:06 ` [RFC PATCH v7 05/16] ipe: add LSM hooks on execution and kernel read deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 20:04   ` Casey Schaufler
2021-10-13 20:04     ` [dm-devel] " Casey Schaufler
2021-10-13 20:04     ` Casey Schaufler
2021-10-15 19:25     ` Deven Bowers
2021-10-15 19:25       ` Deven Bowers
2021-10-15 19:25       ` [dm-devel] " Deven Bowers
2021-10-25 12:22   ` Roberto Sassu
2021-10-25 12:22     ` Roberto Sassu
2021-10-25 12:22     ` [dm-devel] " Roberto Sassu
2021-10-26 19:03     ` Deven Bowers
2021-10-26 19:03       ` Deven Bowers
2021-10-26 19:03       ` [dm-devel] " Deven Bowers
2021-10-27  8:56       ` Roberto Sassu
2021-10-27  8:56         ` Roberto Sassu
2021-10-27  8:56         ` [dm-devel] " Roberto Sassu
2021-10-13 19:06 ` [RFC PATCH v7 06/16] uapi|audit: add trust audit message definitions deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 07/16] ipe: add auditing support deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 20:02   ` Steve Grubb
2021-10-13 20:02     ` [dm-devel] " Steve Grubb
2021-10-13 20:02     ` Steve Grubb
2021-10-15 19:25     ` Deven Bowers
2021-10-15 19:25       ` Deven Bowers
2021-10-15 19:25       ` [dm-devel] " Deven Bowers
2021-11-02 19:44       ` Steve Grubb
2021-11-02 19:44         ` [dm-devel] " Steve Grubb
2021-11-02 19:44         ` Steve Grubb
2021-11-04 16:59         ` Deven Bowers
2021-11-04 16:59           ` Deven Bowers
2021-11-04 16:59           ` [dm-devel] " Deven Bowers
2021-10-13 22:54   ` Randy Dunlap
2021-10-13 22:54     ` Randy Dunlap
2021-10-13 22:54     ` [dm-devel] " Randy Dunlap
2021-10-15 19:25     ` Deven Bowers
2021-10-15 19:25       ` Deven Bowers
2021-10-15 19:25       ` [dm-devel] " Deven Bowers
2021-10-15 19:50       ` Randy Dunlap
2021-10-15 19:50         ` Randy Dunlap
2021-10-15 19:50         ` [dm-devel] " Randy Dunlap
2021-10-26 19:03         ` Deven Bowers
2021-10-26 19:03           ` Deven Bowers
2021-10-26 19:03           ` [dm-devel] " Deven Bowers
2021-10-13 19:06 ` [RFC PATCH v7 08/16] ipe: add permissive toggle deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 09/16] ipe: introduce 'boot_verified' as a trust provider deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 19:06 ` deven.desai [this message]
2021-10-13 19:06   ` [RFC PATCH v7 10/16] fs|dm-verity: add block_dev LSM blob and submit dm-verity data deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 11/16] ipe: add support for dm-verity as a trust provider deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-11-25  9:37   ` Roberto Sassu
2021-11-25  9:37     ` Roberto Sassu
2021-11-25  9:37     ` [dm-devel] " Roberto Sassu
2021-11-30 18:55     ` Deven Bowers
2021-11-30 18:55       ` Deven Bowers
2021-11-30 18:55       ` [dm-devel] " Deven Bowers
2021-12-01 16:37       ` [RFC][PATCH] device mapper: Add builtin function dm_get_status() Roberto Sassu
2021-12-01 16:37         ` Roberto Sassu
2021-12-01 16:37         ` [dm-devel] " Roberto Sassu
2021-12-01 16:43         ` Roberto Sassu
2021-12-01 16:43           ` Roberto Sassu
2021-12-01 16:43           ` [dm-devel] " Roberto Sassu
2021-12-02  7:20         ` Christoph Hellwig
2021-12-02  7:20           ` Christoph Hellwig
2021-12-02  7:20           ` [dm-devel] " Christoph Hellwig
2021-12-02  7:59           ` Roberto Sassu
2021-12-02  7:59             ` Roberto Sassu
2021-12-02  7:59             ` [dm-devel] " Roberto Sassu
2021-12-02  8:44             ` Christoph Hellwig
2021-12-02  8:44               ` Christoph Hellwig
2021-12-02  8:44               ` [dm-devel] " Christoph Hellwig
2021-12-02  9:29               ` Roberto Sassu
2021-12-02  9:29                 ` Roberto Sassu
2021-12-02  9:29                 ` [dm-devel] " Roberto Sassu
2021-12-03  6:52                 ` Christoph Hellwig
2021-12-03  6:52                   ` Christoph Hellwig
2021-12-03  6:52                   ` [dm-devel] " Christoph Hellwig
2021-12-03 10:20                   ` Roberto Sassu
2021-12-03 10:20                     ` Roberto Sassu
2021-12-03 10:20                     ` [dm-devel] " Roberto Sassu
2021-12-06 10:57                     ` Roberto Sassu
2021-12-06 10:57                       ` Roberto Sassu
2021-12-06 10:57                       ` [dm-devel] " Roberto Sassu
2021-10-13 19:06 ` [RFC PATCH v7 12/16] fsverity|security: add security hooks to fsverity digest and signature deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 19:24   ` Eric Biggers
2021-10-13 19:24     ` Eric Biggers
2021-10-13 19:24     ` [dm-devel] " Eric Biggers
2021-10-15 19:25     ` Deven Bowers
2021-10-15 19:25       ` Deven Bowers
2021-10-15 19:25       ` [dm-devel] " Deven Bowers
2021-10-15 20:11       ` Eric Biggers
2021-10-15 20:11         ` Eric Biggers
2021-10-15 20:11         ` [dm-devel] " Eric Biggers
2021-10-20 15:08         ` Roberto Sassu
2021-10-20 15:08           ` [dm-devel] " Roberto Sassu
2021-10-20 15:08           ` Roberto Sassu
2021-10-22 16:31           ` Roberto Sassu
2021-10-22 16:31             ` Roberto Sassu
2021-10-22 16:31             ` [dm-devel] " Roberto Sassu
2021-10-26 19:03             ` Deven Bowers
2021-10-26 19:03               ` Deven Bowers
2021-10-26 19:03               ` [dm-devel] " Deven Bowers
2021-10-27  8:41               ` Roberto Sassu
2021-10-27  8:41                 ` Roberto Sassu
2021-10-27  8:41                 ` [dm-devel] " Roberto Sassu
2021-10-26 19:03         ` Deven Bowers
2021-10-26 19:03           ` Deven Bowers
2021-10-26 19:03           ` [dm-devel] " Deven Bowers
2021-10-27  9:34           ` Roberto Sassu
2021-10-27  9:34             ` Roberto Sassu
2021-10-27  9:34             ` [dm-devel] " Roberto Sassu
2021-10-28  3:48           ` Eric Biggers
2021-10-28  3:48             ` Eric Biggers
2021-10-28  3:48             ` [dm-devel] " Eric Biggers
2021-10-28 18:11             ` Deven Bowers
2021-10-28 18:11               ` Deven Bowers
2021-10-28 18:11               ` [dm-devel] " Deven Bowers
2021-11-03 12:28       ` Roberto Sassu
2021-11-03 12:28         ` Roberto Sassu
2021-11-03 12:28         ` [dm-devel] " Roberto Sassu
2021-11-04 17:12         ` Deven Bowers
2021-11-04 17:12           ` [dm-devel] " Deven Bowers
2021-11-04 17:12           ` Deven Bowers
2021-10-13 19:06 ` [RFC PATCH v7 13/16] ipe: enable support for fs-verity as a trust provider deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-27 11:55   ` kernel test robot
2021-10-13 19:06 ` [RFC PATCH v7 14/16] scripts: add boot policy generation program deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-11-03 16:43   ` Roberto Sassu
2021-11-03 16:43     ` Roberto Sassu
2021-11-03 16:43     ` [dm-devel] " Roberto Sassu
2021-11-03 16:53     ` Roberto Sassu
2021-11-03 16:53       ` Roberto Sassu
2021-11-03 16:53       ` [dm-devel] " Roberto Sassu
2021-11-04 16:52       ` Deven Bowers
2021-11-04 16:52         ` Deven Bowers
2021-11-04 16:52         ` [dm-devel] " Deven Bowers
2021-10-13 19:06 ` [RFC PATCH v7 15/16] ipe: kunit tests deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 16/16] documentation: add ipe documentation deven.desai
2021-10-13 19:06   ` deven.desai
2021-10-13 19:06   ` [dm-devel] " deven.desai
2021-10-25 11:30 ` [RFC PATCH v7 00/16] Integrity Policy Enforcement (IPE) Roberto Sassu
2021-10-25 11:30   ` Roberto Sassu
2021-10-25 11:30   ` [dm-devel] " Roberto Sassu
2021-10-26 19:03   ` Deven Bowers
2021-10-26 19:03     ` Deven Bowers
2021-10-26 19:03     ` [dm-devel] " Deven Bowers
2021-10-27  8:26     ` Roberto Sassu
2021-10-27  8:26       ` Roberto Sassu
2021-10-27  8:26       ` [dm-devel] " Roberto Sassu
2021-10-28 20:36       ` Deven Bowers
2021-10-28 20:36         ` Deven Bowers
2021-10-28 20:36         ` [dm-devel] " Deven Bowers

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=1634151995-16266-11-git-send-email-deven.desai@linux.microsoft.com \
    --to=deven.desai@linux.microsoft.com \
    --cc=agk@redhat.com \
    --cc=axboe@kernel.dk \
    --cc=corbet@lwn.net \
    --cc=dm-devel@redhat.com \
    --cc=ebiggers@kernel.org \
    --cc=eparis@redhat.com \
    --cc=jannh@google.com \
    --cc=jmorris@namei.org \
    --cc=linux-audit@redhat.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fscrypt@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@redhat.com \
    --cc=tytso@mit.edu \
    /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.