Received: by 2002:a05:7412:251c:b0:e2:908c:2ebd with SMTP id w28csp1637970rda; Mon, 23 Oct 2023 20:54:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHB9BTCbWVpq0aRJPnt4np+dVIXwC6EnevEKe77my+PwBKzVa9x6nWg+r5lbiRf1dIYFFdM X-Received: by 2002:a05:6871:b22:b0:1e9:af65:e30b with SMTP id fq34-20020a0568710b2200b001e9af65e30bmr14044910oab.38.1698119642947; Mon, 23 Oct 2023 20:54:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698119642; cv=none; d=google.com; s=arc-20160816; b=EfHGoj9lFk37My4gZACNP7AK2zciTiqllkG/0jAEx2DSGnWVVGcwNzbXjZmpsz7ng/ HKRYoqRYaPR9Ad85zk/l67BL3xbqaxurzAgDHXkKaKH85X3Bz1Ct3ndGMt9Ft0g7FjEy dqdil9CGPOvdWaDXqcfBphT32pGvUJFSLRJQHBbVNg7SFx9EYJ7JAjFbc5nY4nbqQrLx WU3ebZoIh7ixgYy3aZIAX/i8k3/SYe+2m8t85Vrt3sgjZiH7P2P6Ram5yJ/eJsGOvDjl ZBoPCG+jxOCMkW2hgj1+bS/Q5nRK1hmcOchLJ9hJQtHM+f7fyNbRJUslxJePKcnOQrYN +SlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:references:subject:cc:to:from :message-id:date:dkim-signature; bh=+OAIYWmjm+PdaW89yu77Rv5QnSbxzDq+IaV0d/zq7nk=; fh=fHHNkGg+NzKoJxHGMh0JSMLpg18Ht1OPApOBL8ui3GA=; b=kVvJOw0sf2jPmahp5B6E6v2/YAT0k0MdYhL0MCTPnKl86T0uS5fY9bW6awx+boNwXp ++7Lzb3B+6FmBmNDUTSFj8B9cZ8+RkoWgp8vCjF2SzpVd2uCU624XdxmcUoWWVRiuNfE gZY4ausvKxe8fvWR3V7L3A8WtT0NSfde2D+d8iGQ0yeqOwJTkcFqvXDESMN+mDDPbA7s j5UDsdxFqSXp8jIyel8ruoHN/BDWYujvek8C80DROIgzlLW8JXLZqWbxIaI3WmzUt4sD aQQSlHGm2AL8NwdpI50MWZgWzGDCEygpYdtQIla6wDd/2KeK3sLO7y7WjXj+91csPBAD w0Pw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@paul-moore.com header.s=google header.b="LSSZPb/z"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=paul-moore.com Return-Path: Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id ka24-20020a056a00939800b0068bf645ac9bsi7820118pfb.238.2023.10.23.20.54.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Oct 2023 20:54:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@paul-moore.com header.s=google header.b="LSSZPb/z"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=paul-moore.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id B6850802F948; Mon, 23 Oct 2023 20:53:59 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232254AbjJXDxs (ORCPT + 99 others); Mon, 23 Oct 2023 23:53:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232222AbjJXDws (ORCPT ); Mon, 23 Oct 2023 23:52:48 -0400 Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6226210FF for ; Mon, 23 Oct 2023 20:52:34 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id af79cd13be357-778711ee748so312733985a.2 for ; Mon, 23 Oct 2023 20:52:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paul-moore.com; s=google; t=1698119553; x=1698724353; darn=vger.kernel.org; h=in-reply-to:references:subject:cc:to:from:message-id:date:from:to :cc:subject:date:message-id:reply-to; bh=+OAIYWmjm+PdaW89yu77Rv5QnSbxzDq+IaV0d/zq7nk=; b=LSSZPb/zqX3PlhDLzlYm2E36oKt+M19zLutTLU6lGsaenxAi/Fku9sJ+D0OtnuthLH g+tbWEyqiam5mv6oPDdYqvD+OpaCzyS4oW7qPuilPREfsQwHIsOHF5YqRzFg5VRQ1t2n Rrk59+Rg3p6+dePcDfo4Ntl0J/boxKYHQmPtL78JonF3aDfBPokzXQepC57T002fPgAa 1ldxh4fjBfRQ7PuRNbZ5PDyB1Q3b2iBcQMxGjG3vwcIXg5ow4KcZInp9ArCveL/48U23 2cc6RPJuEW0gzhOQRgwZfH5cr/or4jbC0yTL6jmiXC+x6Q/RVITBOHyyA7Z4q4Pt9Efd cv7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698119553; x=1698724353; h=in-reply-to:references:subject:cc:to:from:message-id:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+OAIYWmjm+PdaW89yu77Rv5QnSbxzDq+IaV0d/zq7nk=; b=xEsosgrM5KENiGkrf/n6uxj25rscdMX4JDrD7KbaQAEEcHHbsXwriPXr66QwkbE/Zc bTeIIEeWMNUbxoxS+uQ1w+6N/9l5B/Q+TrcQ0lxLcRTnfH8aOQB5wpfhLF3faOgYjfgp TiSmrk4/5QwIoybpyxZVfYmU+CsRU9X9uf1yonn2qs7Kolqa81WdduCH6X/lD8ijTPy/ KbyKT4TZwgZvYtauZHq09xv11n+/iairzbkRTpccbHkxY+Fj6L2RFcpkt4YZGc8Z37Ux EAD4FS5IbMMZ1SLR0aNxE9/xbt/ruX4y8Drwk+iyNqDucLzh+wumuxSxpOlcYfaUVOAe kUJQ== X-Gm-Message-State: AOJu0YwfVCMJQDSQIL9t5NjPBfmtvadw/57XvtmU8u9lV8stdf2bYcPT Wayxct2H5LXAMBwiofrfy+7Y X-Received: by 2002:a05:620a:460a:b0:778:8f29:5e68 with SMTP id br10-20020a05620a460a00b007788f295e68mr14288780qkb.26.1698119553423; Mon, 23 Oct 2023 20:52:33 -0700 (PDT) Received: from localhost ([70.22.175.108]) by smtp.gmail.com with ESMTPSA id vr3-20020a05620a55a300b0076f18be9a64sm3183283qkn.81.2023.10.23.20.52.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Oct 2023 20:52:32 -0700 (PDT) Date: Mon, 23 Oct 2023 23:52:32 -0400 Message-ID: From: Paul Moore To: Fan Wu , 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 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@redhat.com, audit@vger.kernel.org, roberto.sassu@huawei.com, linux-kernel@vger.kernel.org, Deven Bowers , Fan Wu Subject: Re: [PATCH RFC v11 14/19] ipe: add support for dm-verity as a trust provider References: <1696457386-3010-15-git-send-email-wufan@linux.microsoft.com> In-Reply-To: <1696457386-3010-15-git-send-email-wufan@linux.microsoft.com> X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Mon, 23 Oct 2023 20:53:59 -0700 (PDT) On Oct 4, 2023 Fan Wu wrote: > > 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 > Signed-off-by: Fan Wu > --- > v2: > + No Changes > > v3: > + No changes > > v4: > + No changes > > v5: > + No changes > > v6: > + Fix an improper cleanup that can result in > a leak > > v7: > + Squash patch 08/12, 10/12 to [11/16] > > v8: > + Undo squash of 08/12, 10/12 - separating drivers/md/ from security/ > & block/ > + Use common-audit function for dmverity_signature. > + Change implementation for storing the dm-verity digest to use the > newly introduced dm_verity_digest structure introduced in patch > 14/20. > > v9: > + Adapt to the new parser > > v10: > + Select the Kconfig when all dependencies are enabled > > v11: > + No changes > --- > security/ipe/Kconfig | 18 +++++ > security/ipe/Makefile | 1 + > security/ipe/audit.c | 31 +++++++- > security/ipe/digest.c | 142 +++++++++++++++++++++++++++++++++++ > security/ipe/digest.h | 26 +++++++ > security/ipe/eval.c | 101 ++++++++++++++++++++++++- > security/ipe/eval.h | 13 ++++ > security/ipe/hooks.c | 51 +++++++++++++ > security/ipe/hooks.h | 8 ++ > security/ipe/ipe.c | 15 ++++ > security/ipe/ipe.h | 4 + > security/ipe/policy.h | 3 + > security/ipe/policy_parser.c | 24 +++++- > 13 files changed, 433 insertions(+), 4 deletions(-) > create mode 100644 security/ipe/digest.c > create mode 100644 security/ipe/digest.h ... > diff --git a/security/ipe/audit.c b/security/ipe/audit.c > index 0dd5f10c318f..b5c58655ac74 100644 > --- a/security/ipe/audit.c > +++ b/security/ipe/audit.c > @@ -13,6 +13,7 @@ > #include "hooks.h" > #include "policy.h" > #include "audit.h" > +#include "digest.h" > > #define ACTSTR(x) ((x) == IPE_ACTION_ALLOW ? "ALLOW" : "DENY") > > @@ -40,8 +41,29 @@ static const char *const audit_op_names[__IPE_OP_MAX] = { > static const char *const audit_prop_names[__IPE_PROP_MAX] = { > "boot_verified=FALSE", > "boot_verified=TRUE", > +#ifdef CONFIG_IPE_PROP_DM_VERITY > + "dmverity_roothash=", > + "dmverity_signature=FALSE", > + "dmverity_signature=TRUE", > +#endif /* CONFIG_IPE_PROP_DM_VERITY */ > }; > > +#ifdef CONFIG_IPE_PROP_DM_VERITY > +/** > + * audit_dmv_roothash - audit a roothash of a dmverity volume. > + * @ab: Supplies a pointer to the audit_buffer to append to. > + * @r: Supplies a pointer to the digest structure. > + */ > +static void audit_dmv_roothash(struct audit_buffer *ab, const void *rh) > +{ > + ipe_digest_audit(ab, rh); > +} > +#else > +static void audit_dmv_roothash(struct audit_buffer *ab, const void *rh) > +{ > +} > +#endif /* CONFIG_IPE_PROP_DM_VERITY */ Since the "dmverity_roothash=" field name is going to be written to the audit record regardless of CONFIG_IPE_PROP_DM_VERITY we should ensure that it has a value of "?" instead of nothing. To fix that I would suggest something like this: #else static void audit_dmv_roothash(struct audit_buffer *ab, const void *rh) { audit_log_format(ab, "?"); } #endif /* CONFIG_IPE_PROP_DM_VERITY */ > /** > * audit_rule - audit an IPE policy rule approximation. > * @ab: Supplies a pointer to the audit_buffer to append to. > @@ -53,8 +75,13 @@ static void audit_rule(struct audit_buffer *ab, const struct ipe_rule *r) > > audit_log_format(ab, "rule=\"op=%s ", audit_op_names[r->op]); > > - list_for_each_entry(ptr, &r->props, next) > - audit_log_format(ab, "%s ", audit_prop_names[ptr->type]); > + list_for_each_entry(ptr, &r->props, next) { > + audit_log_format(ab, "%s", audit_prop_names[ptr->type]); > + if (ptr->type == IPE_PROP_DMV_ROOTHASH) > + audit_dmv_roothash(ab, ptr->value); If you wanted to avoid the roothash change above, you could change the code here so it didn't always write "dmverity_roothash=" into the audit record. > + audit_log_format(ab, " "); > + } > > audit_log_format(ab, "action=%s\"", ACTSTR(r->action)); > } > diff --git a/security/ipe/digest.c b/security/ipe/digest.c > new file mode 100644 > index 000000000000..7a42ca71880c > --- /dev/null > +++ b/security/ipe/digest.c > @@ -0,0 +1,142 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) Microsoft Corporation. All rights reserved. > + */ > + > +#include "digest.h" > + > +/** > + * ipe_digest_parse - parse a digest in IPE's policy. > + * @valstr: Supplies the string parsed from the policy. > + * @value: Supplies a pointer to be populated with the result. > + * > + * Digests in IPE are defined in a standard way: > + * : > + * > + * Use this function to create a property to parse the digest > + * consistently. The parsed digest will be saved in @value in IPE's > + * policy. > + * > + * Return: > + * * 0 - OK > + * * !0 - Error > + */ > +int ipe_digest_parse(const char *valstr, void **value) Why is @value void? You should make it a digest_info type or simply skip the second parameter and return a digest_info pointer. > +{ > + char *sep, *raw_digest; > + size_t raw_digest_len; > + int rc = 0; > + u8 *digest = NULL; > + struct digest_info *info = NULL; > + > + info = kzalloc(sizeof(*info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + sep = strchr(valstr, ':'); > + if (!sep) { > + rc = -EBADMSG; > + goto err; > + } > + > + info->alg = kstrndup(valstr, sep - valstr, GFP_KERNEL); > + if (!info->alg) { > + rc = -ENOMEM; > + goto err; > + } > + > + raw_digest = sep + 1; > + raw_digest_len = strlen(raw_digest); > + info->raw_digest = kstrndup(raw_digest, raw_digest_len, GFP_KERNEL); Since you're running a strlen() over @raw_digest, you might as well just use kstrdup() instead of kstrndup(). > + if (!info->raw_digest) { > + rc = -ENOMEM; > + goto err_free_alg; > + } > + > + info->digest_len = (raw_digest_len + 1) / 2; > + digest = kzalloc(info->digest_len, GFP_KERNEL); > + if (!digest) { > + rc = -ENOMEM; > + goto err_free_raw; > + } > + > + rc = hex2bin(digest, raw_digest, info->digest_len); > + if (rc < 0) { > + rc = -EINVAL; > + goto err_free_raw; > + } > + > + info->digest = digest; > + *value = info; > + return 0; > + > +err_free_raw: > + kfree(info->raw_digest); > +err_free_alg: > + kfree(info->alg); > +err: > + kfree(digest); > + kfree(info); > + return rc; > +} > + > +/** > + * ipe_digest_eval - evaluate an IPE digest against another digest. > + * @expect: Supplies the policy-provided digest value. > + * @digest: Supplies the digest to compare against the policy digest value. > + * @digest_len: The length of @digest. > + * @alg: Supplies the name of the algorithm used to calculated @digest. > + * > + * Return: > + * * true - digests match > + * * false - digests do not match > + */ > +bool ipe_digest_eval(const void *expect, const u8 *digest, size_t digest_len, > + const char *alg) Similar to the above, why not make the @expect parameter a digest_info type? Also, why not pass a second digest_info parameter instead of a separate @digest, @digest_len, and @alg? > +{ > + const struct digest_info *info = (struct digest_info *)expect; > + > + return (digest_len == info->digest_len) && !strcmp(alg, info->alg) && > + (!memcmp(info->digest, digest, info->digest_len)); > +} > + > +/** > + * ipe_digest_free - free an IPE digest. > + * @value: Supplies a pointer the policy-provided digest value to free. > + */ > +void ipe_digest_free(void **value) Another digest_info parameter/type issue. > +{ > + struct digest_info *info = (struct digest_info *)(*value); > + > + if (IS_ERR_OR_NULL(info)) > + return; > + > + kfree(info->alg); > + kfree(info->raw_digest); > + kfree(info->digest); > + kfree(info); > +} > + > +/** > + * ipe_digest_audit - audit a digest that was sourced from IPE's policy. > + * @ab: Supplies the audit_buffer to append the formatted result. > + * @val: Supplies a pointer to source the audit record from. > + * > + * Digests in IPE are defined in a standard way: > + * : > + * > + * Use this function to create a property to audit the digest > + * consistently. > + * > + * Return: > + * 0 - OK > + * !0 - Error > + */ > +void ipe_digest_audit(struct audit_buffer *ab, const void *val) Another digest_info parameter/type issue. > +{ > + const struct digest_info *info = (struct digest_info *)val; > + > + audit_log_untrustedstring(ab, info->alg); > + audit_log_format(ab, ":"); > + audit_log_untrustedstring(ab, info->raw_digest); > +} ... > diff --git a/security/ipe/eval.c b/security/ipe/eval.c > index 78c54ff1fdd3..82ad48d7aa3d 100644 > --- a/security/ipe/eval.c > +++ b/security/ipe/eval.c > @@ -69,15 +88,89 @@ void build_eval_ctx(struct ipe_eval_ctx *ctx, > const struct file *file, > enum ipe_op_type op) > { > + struct inode *ino = NULL; > + > if (op == IPE_OP_EXEC && file) > pin_sb(FILE_SUPERBLOCK(file)); > > ctx->file = file; > ctx->op = op; > > - if (file) > + if (file) { > ctx->from_init_sb = from_pinned(FILE_SUPERBLOCK(file)); > + ino = d_real_inode(file->f_path.dentry); > + build_ipe_bdev_ctx(ctx, ino); You don't need @ino. build_ipe_bdev_ctx(ctx, d_real_inode(file->f_path.dentry)); > + } > +} > + > +#ifdef CONFIG_IPE_PROP_DM_VERITY > +/** > + * evaluate_dmv_roothash - Evaluate @ctx against a dmv roothash property. > + * @ctx: Supplies a pointer to the context being evaluated. > + * @p: Supplies a pointer to the property being evaluated. > + * > + * Return: > + * * true - The current @ctx match the @p > + * * false - The current @ctx doesn't match the @p > + */ > +static bool evaluate_dmv_roothash(const struct ipe_eval_ctx *const ctx, > + struct ipe_prop *p) > +{ > + return !!ctx->ipe_bdev && > + ipe_digest_eval(p->value, > + ctx->ipe_bdev->digest, > + ctx->ipe_bdev->digest_len, > + ctx->ipe_bdev->digest_algo); Building on my comments above in ipe_digest_eval(), if you convert it to use digest_info structs this is simplified: ipe_digest_eval(p->vlaue, ctx->ipe_bdev) > +} > + > +/** > + * evaluate_dmv_sig_false: Analyze @ctx against a dmv sig false property. > + * @ctx: Supplies a pointer to the context being evaluated. > + * @p: Supplies a pointer to the property being evaluated. > + * > + * Return: > + * * true - The current @ctx match the @p > + * * false - The current @ctx doesn't match the @p > + */ > +static bool evaluate_dmv_sig_false(const struct ipe_eval_ctx *const ctx, > + struct ipe_prop *p) > +{ > + return !ctx->ipe_bdev || (!ctx->ipe_bdev->dm_verity_signed); > +} > + > +/** > + * evaluate_dmv_sig_true: Analyze @ctx against a dmv sig true property. > + * @ctx: Supplies a pointer to the context being evaluated. > + * @p: Supplies a pointer to the property being evaluated. > + * > + * Return: > + * * true - The current @ctx match the @p > + * * false - The current @ctx doesn't match the @p > + */ > +static bool evaluate_dmv_sig_true(const struct ipe_eval_ctx *const ctx, > + struct ipe_prop *p) > +{ > + return ctx->ipe_bdev && (!!ctx->ipe_bdev->dm_verity_signed); > +} Do you need both evaluate_dmv_sig_true() and evaluate_dmv_sig_false()? If yes, you should make one call the other and return the inverse to help ensure there are no oddities. > diff --git a/security/ipe/hooks.c b/security/ipe/hooks.c > index e9386762a597..8b8031e66f36 100644 > --- a/security/ipe/hooks.c > +++ b/security/ipe/hooks.c > @@ -193,3 +196,51 @@ void ipe_sb_free_security(struct super_block *mnt_sb) > { > ipe_invalidate_pinned_sb(mnt_sb); > } > + > +#ifdef CONFIG_IPE_PROP_DM_VERITY > +/** > + * ipe_bdev_free_security - free IPE's LSM blob of 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->digest); > + kfree(blob->digest_algo); > +} > + > +/** > + * ipe_bdev_setsecurity - save data from a bdev to 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_ROOTHASH_SEC_NAME)) { > + const struct dm_verity_digest *digest = value; > + > + blob->digest = kmemdup(digest->digest, digest->digest_len, GFP_KERNEL); > + if (!blob->digest) > + return -ENOMEM; > + > + blob->digest_algo = kstrdup_const(digest->algo, GFP_KERNEL); > + if (!blob->digest_algo) > + return -ENOMEM; You need to cleanup @blob on error so you don't leak ipe_bdev::digest. > + blob->digest_len = digest->digest_len; > + return 0; > + } else if (!strcmp(key, DM_VERITY_SIGNATURE_SEC_NAME)) { > + blob->dm_verity_signed = true; > + return 0; > + } > + > + return -EOPNOTSUPP; > +} > +#endif /* CONFIG_IPE_PROP_DM_VERITY */ -- paul-moore.com