From: Roberto Sassu <roberto.sassu@huawei.com>
To: "deven.desai@linux.microsoft.com"
<deven.desai@linux.microsoft.com>,
"corbet@lwn.net" <corbet@lwn.net>,
"axboe@kernel.dk" <axboe@kernel.dk>,
"agk@redhat.com" <agk@redhat.com>,
"snitzer@redhat.com" <snitzer@redhat.com>,
"ebiggers@kernel.org" <ebiggers@kernel.org>,
"tytso@mit.edu" <tytso@mit.edu>,
"paul@paul-moore.com" <paul@paul-moore.com>,
"eparis@redhat.com" <eparis@redhat.com>,
"jmorris@namei.org" <jmorris@namei.org>,
"serge@hallyn.com" <serge@hallyn.com>
Cc: "linux-security-module@vger.kernel.org"
<linux-security-module@vger.kernel.org>,
"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
"jannh@google.com" <jannh@google.com>,
"linux-fscrypt@vger.kernel.org" <linux-fscrypt@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-block@vger.kernel.org" <linux-block@vger.kernel.org>,
"dm-devel@redhat.com" <dm-devel@redhat.com>,
"linux-audit@redhat.com" <linux-audit@redhat.com>,
"tusharsu@linux.microsoft.com" <tusharsu@linux.microsoft.com>,
"linux-integrity@vger.kernel.org"
<linux-integrity@vger.kernel.org>
Subject: RE: [RFC PATCH v7 11/16] ipe: add support for dm-verity as a trust provider
Date: Thu, 25 Nov 2021 09:37:51 +0000 [thread overview]
Message-ID: <721462c3da064d359ca3c83845298ccf@huawei.com> (raw)
In-Reply-To: <1634151995-16266-12-git-send-email-deven.desai@linux.microsoft.com>
> From: deven.desai@linux.microsoft.com
> [mailto:deven.desai@linux.microsoft.com]
> Sent: Wednesday, October 13, 2021 9:07 PM
> From: Deven Bowers <deven.desai@linux.microsoft.com>
>
> Allows author of IPE policy to indicate trust for a singular dm-verity
> volume, identified by roothash, through "dmverity_roothash" and all
> signed dm-verity volumes, through "dmverity_signature".
>
> Signed-off-by: Deven Bowers <deven.desai@linux.microsoft.com>
> ---
>
> Relevant changes since v6:
> * Squash patch 08/12, 10/12 to [11/16]
>
> ---
> security/ipe/eval.c | 5 ++
> security/ipe/eval.h | 10 +++
> security/ipe/hooks.c | 48 ++++++++++++++
> security/ipe/hooks.h | 6 ++
> security/ipe/ipe.c | 9 +++
> security/ipe/ipe.h | 3 +
> security/ipe/modules/Kconfig | 23 +++++++
> security/ipe/modules/Makefile | 2 +
> security/ipe/modules/dmverity_roothash.c | 80 +++++++++++++++++++++++
> security/ipe/modules/dmverity_signature.c | 25 +++++++
> 10 files changed, 211 insertions(+)
> create mode 100644 security/ipe/modules/dmverity_roothash.c
> create mode 100644 security/ipe/modules/dmverity_signature.c
>
> diff --git a/security/ipe/eval.c b/security/ipe/eval.c
> index 361efccebad4..facc05c753f4 100644
> --- a/security/ipe/eval.c
> +++ b/security/ipe/eval.c
> @@ -23,6 +23,7 @@ static struct super_block *pinned_sb;
> static DEFINE_SPINLOCK(pin_lock);
>
> #define FILE_SUPERBLOCK(f) ((f)->f_path.mnt->mnt_sb)
> +#define FILE_BLOCK_DEV(f) (FILE_SUPERBLOCK(f)->s_bdev)
>
> /**
> * pin_sb: pin the underlying superblock of @f, marking it as trusted
> @@ -95,6 +96,10 @@ static struct ipe_eval_ctx *build_ctx(const struct file *file,
> ctx->hook = hook;
> ctx->ci_ctx = ipe_current_ctx();
> ctx->from_init_sb = from_pinned(file);
> + if (file) {
> + if (FILE_BLOCK_DEV(file))
> + ctx->ipe_bdev = ipe_bdev(FILE_BLOCK_DEV(file));
> + }
>
> return ctx;
> }
> diff --git a/security/ipe/eval.h b/security/ipe/eval.h
> index 42fb7fdf2599..25d2d8d55702 100644
> --- a/security/ipe/eval.h
> +++ b/security/ipe/eval.h
> @@ -13,6 +13,14 @@
> #include "hooks.h"
> #include "policy.h"
>
> +struct ipe_bdev {
> + const u8 *sigdata;
> + size_t siglen;
> +
> + const u8 *hash;
> + size_t hashlen;
> +};
> +
> struct ipe_eval_ctx {
> enum ipe_hook hook;
> enum ipe_operation op;
> @@ -20,6 +28,8 @@ struct ipe_eval_ctx {
> const struct file *file;
> struct ipe_context *ci_ctx;
>
> + const struct ipe_bdev *ipe_bdev;
> +
> bool from_init_sb;
> };
>
> diff --git a/security/ipe/hooks.c b/security/ipe/hooks.c
> index 2d4a4f0eead0..470fb48e490c 100644
> --- a/security/ipe/hooks.c
> +++ b/security/ipe/hooks.c
> @@ -13,6 +13,7 @@
> #include <linux/types.h>
> #include <linux/refcount.h>
> #include <linux/rcupdate.h>
> +#include <linux/blk_types.h>
> #include <linux/binfmts.h>
> #include <linux/mman.h>
>
> @@ -219,3 +220,50 @@ void ipe_sb_free_security(struct super_block *mnt_sb)
> {
> ipe_invalidate_pinned_sb(mnt_sb);
> }
> +
> +/**
> + * ipe_bdev_free_security: free nested structures within IPE's LSM blob
> + * in block_devices
> + * @bdev: Supplies a pointer to a block_device that contains the structure
> + * to free.
> + */
> +void ipe_bdev_free_security(struct block_device *bdev)
> +{
> + struct ipe_bdev *blob = ipe_bdev(bdev);
> +
> + kfree(blob->sigdata);
> +}
> +
> +/**
> + * ipe_bdev_setsecurity: associate some data from the block device layer
> + * with IPE's LSM blob.
> + * @bdev: Supplies a pointer to a block_device that contains the LSM blob.
> + * @key: Supplies the string key that uniquely identifies the value.
> + * @value: Supplies the value to store.
> + * @len: The length of @value.
> + */
> +int ipe_bdev_setsecurity(struct block_device *bdev, const char *key,
> + const void *value, size_t len)
> +{
> + struct ipe_bdev *blob = ipe_bdev(bdev);
> +
> + if (!strcmp(key, DM_VERITY_SIGNATURE_SEC_NAME)) {
> + blob->siglen = len;
> + blob->sigdata = kmemdup(value, len, GFP_KERNEL);
> + if (!blob->sigdata)
> + return -ENOMEM;
> +
> + return 0;
> + }
> +
> + if (!strcmp(key, DM_VERITY_ROOTHASH_SEC_NAME)) {
> + blob->hashlen = len;
> + blob->hash = kmemdup(value, len, GFP_KERNEL);
> + if (!blob->hash)
> + return -ENOMEM;
> +
> + return 0;
> + }
> +
> + return -ENOSYS;
> +}
> diff --git a/security/ipe/hooks.h b/security/ipe/hooks.h
> index e7f107ab5620..285f35187188 100644
> --- a/security/ipe/hooks.h
> +++ b/security/ipe/hooks.h
> @@ -10,6 +10,7 @@
> #include <linux/sched.h>
> #include <linux/binfmts.h>
> #include <linux/security.h>
> +#include <linux/device-mapper.h>
>
> enum ipe_hook {
> ipe_hook_exec = 0,
> @@ -40,4 +41,9 @@ int ipe_on_kernel_load_data(enum kernel_load_data_id
> id, bool contents);
>
> void ipe_sb_free_security(struct super_block *mnt_sb);
>
> +void ipe_bdev_free_security(struct block_device *bdev);
> +
> +int ipe_bdev_setsecurity(struct block_device *bdev, const char *key,
> + const void *value, size_t len);
> +
> #endif /* IPE_HOOKS_H */
> diff --git a/security/ipe/ipe.c b/security/ipe/ipe.c
> index 1382d50078ec..215936cb4574 100644
> --- a/security/ipe/ipe.c
> +++ b/security/ipe/ipe.c
> @@ -9,6 +9,7 @@
> #include "ipe_parser.h"
> #include "modules/ipe_module.h"
> #include "modules.h"
> +#include "eval.h"
>
> #include <linux/fs.h>
> #include <linux/sched.h>
> @@ -20,8 +21,14 @@
>
> struct lsm_blob_sizes ipe_blobs __lsm_ro_after_init = {
> .lbs_task = sizeof(struct ipe_context __rcu *),
> + .lbs_bdev = sizeof(struct ipe_bdev),
> };
>
> +struct ipe_bdev *ipe_bdev(struct block_device *b)
> +{
> + return b->security + ipe_blobs.lbs_bdev;
> +}
> +
> static struct security_hook_list ipe_hooks[] __lsm_ro_after_init = {
> LSM_HOOK_INIT(task_alloc, ipe_task_alloc),
> LSM_HOOK_INIT(task_free, ipe_task_free),
> @@ -31,6 +38,8 @@ static struct security_hook_list ipe_hooks[]
> __lsm_ro_after_init = {
> LSM_HOOK_INIT(kernel_read_file, ipe_on_kernel_read),
> LSM_HOOK_INIT(kernel_load_data, ipe_on_kernel_load_data),
> LSM_HOOK_INIT(sb_free_security, ipe_sb_free_security),
> + LSM_HOOK_INIT(bdev_free_security, ipe_bdev_free_security),
> + LSM_HOOK_INIT(bdev_setsecurity, ipe_bdev_setsecurity),
> };
>
> /**
> diff --git a/security/ipe/ipe.h b/security/ipe/ipe.h
> index ad16d2bebfec..6b4c7e07f204 100644
> --- a/security/ipe/ipe.h
> +++ b/security/ipe/ipe.h
> @@ -14,10 +14,13 @@
>
> #include <linux/types.h>
> #include <linux/sched.h>
> +#include <linux/blk_types.h>
> #include <linux/lsm_hooks.h>
>
> extern struct lsm_blob_sizes ipe_blobs;
> extern struct ipe_parser __start_ipe_parsers[], __end_ipe_parsers[];
> extern struct ipe_module __start_ipe_modules[], __end_ipe_modules[];
>
> +struct ipe_bdev *ipe_bdev(struct block_device *b);
> +
> #endif /* IPE_H */
> diff --git a/security/ipe/modules/Kconfig b/security/ipe/modules/Kconfig
> index fad96ba534e2..a6ea06cf0737 100644
> --- a/security/ipe/modules/Kconfig
> +++ b/security/ipe/modules/Kconfig
> @@ -16,5 +16,28 @@ config IPE_PROP_BOOT_VERIFIED
>
> If unsure, answer N.
>
> +config IPE_PROP_DM_VERITY_SIGNATURE
> + bool "Enable support for signed dm-verity volumes"
> + depends on DM_VERITY_VERIFY_ROOTHASH_SIG
> + default Y
> + help
> + This option enables the property 'dmverity_signature' in
> + IPE policy. This property evaluates to TRUE when a file
> + is evaluated against a dm-verity volume that was mounted
> + with a signed root-hash.
> +
> + If unsure, answer Y.
> +
> +config IPE_PROP_DM_VERITY_ROOTHASH
> + bool "Enable support for dm-verity volumes"
> + depends on DM_VERITY
> + default Y
> + help
> + This option enables the property 'dmverity_roothash' in
> + IPE policy. This property evaluates to TRUE when a file
> + is evaluated against a dm-verity volume whose root hash
> + matches the supplied value.
> +
> + If unsure, answer Y.
>
> endmenu
> diff --git a/security/ipe/modules/Makefile b/security/ipe/modules/Makefile
> index e0045ec65434..84fadce85193 100644
> --- a/security/ipe/modules/Makefile
> +++ b/security/ipe/modules/Makefile
> @@ -6,3 +6,5 @@
> #
>
> obj-$(CONFIG_IPE_PROP_BOOT_VERIFIED) += boot_verified.o
> +obj-$(CONFIG_IPE_PROP_DM_VERITY_SIGNATURE) += dmverity_signature.o
> +obj-$(CONFIG_IPE_PROP_DM_VERITY_ROOTHASH) += dmverity_roothash.o
> diff --git a/security/ipe/modules/dmverity_roothash.c
> b/security/ipe/modules/dmverity_roothash.c
> new file mode 100644
> index 000000000000..0f82bec3b842
> --- /dev/null
> +++ b/security/ipe/modules/dmverity_roothash.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) Microsoft Corporation. All rights reserved.
> + */
> +
> +#include "ipe_module.h"
> +
> +#include <linux/fs.h>
> +#include <linux/types.h>
> +
> +struct counted_array {
> + size_t len;
> + u8 *data;
> +};
> +
> +static int dvrh_parse(const char *valstr, void **value)
> +{
> + int rv = 0;
> + struct counted_array *arr;
> +
> + arr = kzalloc(sizeof(*arr), GFP_KERNEL);
> + if (!arr) {
> + rv = -ENOMEM;
> + goto err;
> + }
> +
> + arr->len = (strlen(valstr) / 2);
> +
> + arr->data = kzalloc(arr->len, GFP_KERNEL);
> + if (!arr->data) {
> + rv = -ENOMEM;
> + goto err;
> + }
> +
> + rv = hex2bin(arr->data, valstr, arr->len);
> + if (rv != 0)
> + goto err2;
> +
> + *value = arr;
> + return rv;
> +err2:
> + kfree(arr->data);
> +err:
> + kfree(arr);
> + return rv;
> +}
> +
> +static bool dvrh_eval(const struct ipe_eval_ctx *ctx, const void *val)
> +{
> + const u8 *src;
> + struct counted_array *expect = (struct counted_array *)val;
> +
> + if (!ctx->ipe_bdev)
> + return false;
> +
> + if (ctx->ipe_bdev->hashlen != expect->len)
> + return false;
> +
> + src = ctx->ipe_bdev->hash;
> +
> + return !memcmp(expect->data, src, expect->len);
Hi Deven
I was curious to see if determining the property at run-time
could apply also to dm-verity. It seems it could be done
(I omit some checks, I also keep the expected value in hex
format):
---
md = dm_get_md(file_inode(ctx->file)->i_sb->s_dev);
table = dm_get_live_table(md, &srcu_idx);
num_targets = dm_table_get_num_targets(table);
for (i = 0; i < num_targets; i++) {
struct dm_target *ti = dm_table_get_target(table, i);
if (strcmp(ti->type->name, "verity"))
continue;
ti->type->status(ti, STATUSTYPE_IMA, 0, result, sizeof(result));
}
dm_put_live_table(md, srcu_idx);
dm_put(md);
root_digest_ptr = strstr(result, "root_digest=");
return !strncmp(expect->data, root_digest_ptr + 12, expect->len);
---
Only dm_table_get_target() is not exported yet, but I guess it could
be. dm_table_get_num_targets() is exported.
With this code, you would not have to manage security blobs
outside IPE. Maybe you could add a blob for the super block, so
that you verify the dm-verity property just once per filesystem.
Roberto
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Li Peng, Zhong Ronghua
> +}
> +
> +static int dvrh_free(void **val)
> +{
> + struct counted_array *expect = (struct counted_array *)val;
> +
> + kfree(expect->data);
> + kfree(expect);
> +
> + return 0;
> +}
> +
> +IPE_MODULE(dvrh) = {
> + .name = "dmverity_roothash",
> + .version = 1,
> + .parse = dvrh_parse,
> + .free = dvrh_free,
> + .eval = dvrh_eval,
> +};
> diff --git a/security/ipe/modules/dmverity_signature.c
> b/security/ipe/modules/dmverity_signature.c
> new file mode 100644
> index 000000000000..08746fcbcb3e
> --- /dev/null
> +++ b/security/ipe/modules/dmverity_signature.c
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) Microsoft Corporation. All rights reserved.
> + */
> +
> +#include "ipe_module.h"
> +
> +#include <linux/fs.h>
> +#include <linux/types.h>
> +
> +static bool dvv_eval(const struct ipe_eval_ctx *ctx, const void *val)
> +{
> + bool expect = (bool)val;
> + bool eval = ctx->ipe_bdev && (!!ctx->ipe_bdev->sigdata);
> +
> + return expect == eval;
> +}
> +
> +IPE_MODULE(dvv) = {
> + .name = "dmverity_signature",
> + .version = 1,
> + .parse = ipe_bool_parse,
> + .free = NULL,
> + .eval = dvv_eval,
> +};
> --
> 2.33.0
--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit
next prev parent reply other threads:[~2021-11-25 14:29 UTC|newest]
Thread overview: 63+ 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 ` [RFC PATCH v7 01/16] security: add ipe lsm & initial context creation deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 02/16] ipe: add policy parser deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 03/16] ipe: add evaluation loop deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 04/16] ipe: add userspace interface deven.desai
2021-11-03 9:42 ` Roberto Sassu
2021-11-04 16:50 ` 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 20:04 ` Casey Schaufler
2021-10-15 19:25 ` Deven Bowers
2021-10-25 12:22 ` Roberto Sassu
2021-10-26 19:03 ` Deven Bowers
2021-10-27 8:56 ` 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 ` [RFC PATCH v7 07/16] ipe: add auditing support deven.desai
2021-10-13 20:02 ` Steve Grubb
2021-10-15 19:25 ` Deven Bowers
2021-11-02 19:44 ` Steve Grubb
2021-11-04 16:59 ` Deven Bowers
2021-10-13 22:54 ` Randy Dunlap
2021-10-15 19:25 ` Deven Bowers
2021-10-15 19:50 ` Randy Dunlap
2021-10-26 19:03 ` Deven Bowers
2021-10-13 19:06 ` [RFC PATCH v7 08/16] ipe: add permissive toggle 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 ` [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 ` [RFC PATCH v7 11/16] ipe: add support for dm-verity as a trust provider deven.desai
2021-11-25 9:37 ` Roberto Sassu [this message]
2021-11-30 18:55 ` Deven Bowers
2021-12-01 16:37 ` [RFC][PATCH] device mapper: Add builtin function dm_get_status() Roberto Sassu
2021-12-01 16:43 ` Roberto Sassu
2021-12-02 7:20 ` Christoph Hellwig
2021-12-02 7:59 ` Roberto Sassu
2021-12-02 8:44 ` Christoph Hellwig
2021-12-02 9:29 ` Roberto Sassu
2021-12-03 6:52 ` Christoph Hellwig
2021-12-03 10:20 ` Roberto Sassu
2021-12-06 10:57 ` 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:24 ` Eric Biggers
2021-10-15 19:25 ` Deven Bowers
2021-10-15 20:11 ` Eric Biggers
2021-10-20 15:08 ` Roberto Sassu
2021-10-22 16:31 ` Roberto Sassu
2021-10-26 19:03 ` Deven Bowers
2021-10-27 8:41 ` Roberto Sassu
2021-10-26 19:03 ` Deven Bowers
2021-10-27 9:34 ` Roberto Sassu
2021-10-28 3:48 ` Eric Biggers
2021-10-28 18:11 ` Deven Bowers
2021-11-03 12:28 ` Roberto Sassu
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 ` [RFC PATCH v7 14/16] scripts: add boot policy generation program deven.desai
2021-11-03 16:43 ` Roberto Sassu
2021-11-03 16:53 ` Roberto Sassu
2021-11-04 16:52 ` Deven Bowers
2021-10-13 19:06 ` [RFC PATCH v7 15/16] ipe: kunit tests deven.desai
2021-10-13 19:06 ` [RFC PATCH v7 16/16] documentation: add ipe documentation deven.desai
2021-10-25 11:30 ` [RFC PATCH v7 00/16] Integrity Policy Enforcement (IPE) Roberto Sassu
2021-10-26 19:03 ` Deven Bowers
2021-10-27 8:26 ` Roberto Sassu
2021-10-28 20:36 ` 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=721462c3da064d359ca3c83845298ccf@huawei.com \
--to=roberto.sassu@huawei.com \
--cc=agk@redhat.com \
--cc=axboe@kernel.dk \
--cc=corbet@lwn.net \
--cc=deven.desai@linux.microsoft.com \
--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-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@redhat.com \
--cc=tusharsu@linux.microsoft.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).