* Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
From: Eric Biggers @ 2026-02-02 18:30 UTC (permalink / raw)
To: David Howells
Cc: =?UTF-8?q?Mihai-Drosi=20C=C3=A2ju?=, linux, arnd, arnout, atomlin,
bigeasy, chleroy, christian, corbet, coxu, da.gomez, da.gomez,
dmitry.kasatkin, eric.snowberg, f.gruenbichler, jmorris, kpcyrd,
linux-arch, linux-doc, linux-integrity, linux-kbuild,
linux-kernel, linux-modules, linux-security-module, linuxppc-dev,
lkp, maddy, mattia, mcgrof, mpe, nathan, naveen,
nicolas.bouchinet, nicolas.schier, npiggin, nsc, paul, petr.pavlu,
roberto.sassu, samitolvanen, serge, xiujianfeng, zohar
In-Reply-To: <2339369.1770024079@warthog.procyon.org.uk>
On Mon, Feb 02, 2026 at 09:21:19AM +0000, David Howells wrote:
> Eric Biggers <ebiggers@kernel.org> wrote:
>
> > With that being the case, why is there still effort being put into
> > adding more features to module signing? I would think efforts should be
> > focused on hash-based module authentication, i.e. this patchset.
>
> Because it's not just signing of modules
Module signing is indeed about the signing of modules.
> and it's not just modules built with the kernel.
Could you give more details on this use case and why it needs
signatures, as opposed to e.g. loading an additional Merkle tree root
into the kernel to add to the set of allowed modules?
> Also a hash table just of module hashes built into the core
> kernel image will increase the size of the kernel by around a third of a meg
> (on Fedora 43 and assuming SHA512) with uncompressible data.
This patchset already optimizes it to use Merkle tree proofs instead.
While I'm a bit skeptical of the complexity myself (and distros
shouldn't be shipping such an excessively large number of modules in the
first place), if it's indeed needed it's already been solved. It's
still much simpler than the PKCS#7 signature mess.
- Eric
^ permalink raw reply
* Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
From: David Howells @ 2026-02-02 18:38 UTC (permalink / raw)
To: Eric Biggers
Cc: dhowells, =?UTF-8?q?Mihai-Drosi=20C=C3=A2ju?=, linux, arnd,
arnout, atomlin, bigeasy, chleroy, christian, corbet, coxu,
da.gomez, da.gomez, dmitry.kasatkin, eric.snowberg,
f.gruenbichler, jmorris, kpcyrd, linux-arch, linux-doc,
linux-integrity, linux-kbuild, linux-kernel, linux-modules,
linux-security-module, linuxppc-dev, lkp, maddy, mattia, mcgrof,
mpe, nathan, naveen, nicolas.bouchinet, nicolas.schier, npiggin,
nsc, paul, petr.pavlu, roberto.sassu, samitolvanen, serge,
xiujianfeng, zohar
In-Reply-To: <20260202183055.GB2036@quark>
Eric Biggers <ebiggers@kernel.org> wrote:
> On Mon, Feb 02, 2026 at 09:21:19AM +0000, David Howells wrote:
> > Eric Biggers <ebiggers@kernel.org> wrote:
> >
> > > With that being the case, why is there still effort being put into
> > > adding more features to module signing? I would think efforts should be
> > > focused on hash-based module authentication, i.e. this patchset.
> >
> > Because it's not just signing of modules
>
> Module signing is indeed about the signing of modules.
The signature verification stuff in the kernel isn't just used for modules.
kexec, for instance; wifi restriction database for another.
> > and it's not just modules built with the kernel.
>
> Could you give more details on this use case and why it needs
> signatures, as opposed to e.g. loading an additional Merkle tree root
> into the kernel to add to the set of allowed modules?
Because we don't want to, for example, include all the nvidia drivers in our
kernel SRPM.
David
^ permalink raw reply
* Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
From: Eric Biggers @ 2026-02-02 18:47 UTC (permalink / raw)
To: David Howells
Cc: =?UTF-8?q?Mihai-Drosi=20C=C3=A2ju?=, linux, arnd, arnout, atomlin,
bigeasy, chleroy, christian, corbet, coxu, da.gomez, da.gomez,
dmitry.kasatkin, eric.snowberg, f.gruenbichler, jmorris, kpcyrd,
linux-arch, linux-doc, linux-integrity, linux-kbuild,
linux-kernel, linux-modules, linux-security-module, linuxppc-dev,
lkp, maddy, mattia, mcgrof, mpe, nathan, naveen,
nicolas.bouchinet, nicolas.schier, npiggin, nsc, paul, petr.pavlu,
roberto.sassu, samitolvanen, serge, xiujianfeng, zohar
In-Reply-To: <2513499.1770057531@warthog.procyon.org.uk>
On Mon, Feb 02, 2026 at 06:38:51PM +0000, David Howells wrote:
> > Could you give more details on this use case and why it needs
> > signatures, as opposed to e.g. loading an additional Merkle tree root
> > into the kernel to add to the set of allowed modules?
>
> Because we don't want to, for example, include all the nvidia drivers in our
> kernel SRPM.
That doesn't answer my question. Are you trying to say these modules
need to be built later *and* signed using the original signing key?
- Eric
^ permalink raw reply
* Re: [PATCH v16 4/7] pkcs7: Allow the signing algo to do whatever digestion it wants itself
From: Jarkko Sakkinen @ 2026-02-03 0:29 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, Ignat Korchagin, Herbert Xu, Eric Biggers,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Jason A . Donenfeld, Ard Biesheuvel, Stephan Mueller,
linux-crypto, keyrings, linux-modules, linux-kernel
In-Reply-To: <20260202170216.2467036-5-dhowells@redhat.com>
On Mon, Feb 02, 2026 at 05:02:09PM +0000, David Howells wrote:
> Allow the data to be verified in a PKCS#7 or CMS message to be passed
> directly to an asymmetric cipher algorithm (e.g. ML-DSA) if it wants to do
> whatever passes for hashing/digestion itself. The normal digestion of the
> data is then skipped as that would be ignored unless another signed info in
> the message has some other algorithm that needs it.
>
> The 'data to be verified' may be the content of the PKCS#7 message or it
> will be the authenticatedAttributes (signedAttrs if CMS), modified, if
> those are present.
>
> This is done by:
>
> (1) Make ->m and ->m_size point to the data to be verified rather than
> making public_key_verify_signature() access the data directly. This
> is so that keyctl(KEYCTL_PKEY_VERIFY) will still work.
>
> (2) Add a flag, ->algo_takes_data, to indicate that the verification
> algorithm wants to access the data to be verified directly rather than
> having it digested first.
>
> (3) If the PKCS#7 message has authenticatedAttributes (or CMS
> signedAttrs), then the digest contained therein will be validated as
> now, and the modified attrs blob will either be digested or assigned
> to ->m as appropriate.
>
> (4) If present, always copy and modify the authenticatedAttributes (or
> signedAttrs) then digest that in one go rather than calling the shash
> update twice (once for the tag and once for the rest).
>
> (5) For ML-DSA, point ->m to the TBSCertificate instead of digesting it
> and using the digest.
>
> Note that whilst ML-DSA does allow for an "external mu", CMS doesn't yet
> have that standardised.
>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Lukas Wunner <lukas@wunner.de>
> cc: Ignat Korchagin <ignat@cloudflare.com>
> cc: Stephan Mueller <smueller@chronox.de>
> cc: Eric Biggers <ebiggers@kernel.org>
> cc: Herbert Xu <herbert@gondor.apana.org.au>
> cc: keyrings@vger.kernel.org
> cc: linux-crypto@vger.kernel.org
> ---
> crypto/asymmetric_keys/pkcs7_parser.c | 4 +-
> crypto/asymmetric_keys/pkcs7_verify.c | 52 ++++++++++++++++--------
> crypto/asymmetric_keys/signature.c | 3 +-
> crypto/asymmetric_keys/x509_public_key.c | 10 +++++
> include/crypto/public_key.h | 2 +
> 5 files changed, 51 insertions(+), 20 deletions(-)
>
> diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
> index 423d13c47545..3cdbab3b9f50 100644
> --- a/crypto/asymmetric_keys/pkcs7_parser.c
> +++ b/crypto/asymmetric_keys/pkcs7_parser.c
> @@ -599,8 +599,8 @@ int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
> }
>
> /* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
> - sinfo->authattrs = value - (hdrlen - 1);
> - sinfo->authattrs_len = vlen + (hdrlen - 1);
> + sinfo->authattrs = value - hdrlen;
> + sinfo->authattrs_len = vlen + hdrlen;
> return 0;
> }
>
> diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
> index aa085ec6fb1c..06abb9838f95 100644
> --- a/crypto/asymmetric_keys/pkcs7_verify.c
> +++ b/crypto/asymmetric_keys/pkcs7_verify.c
> @@ -30,6 +30,16 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
>
> kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
>
> + if (!sinfo->authattrs && sig->algo_takes_data) {
> + /* There's no intermediate digest and the signature algo
> + * doesn't want the data prehashing.
> + */
> + sig->m = (void *)pkcs7->data;
> + sig->m_size = pkcs7->data_len;
> + sig->m_free = false;
> + return 0;
> + }
> +
> /* The digest was calculated already. */
> if (sig->m)
> return 0;
> @@ -48,9 +58,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
> sig->m_size = crypto_shash_digestsize(tfm);
>
> ret = -ENOMEM;
> - sig->m = kmalloc(sig->m_size, GFP_KERNEL);
> + sig->m = kmalloc(umax(sinfo->authattrs_len, sig->m_size), GFP_KERNEL);
> if (!sig->m)
> goto error_no_desc;
> + sig->m_free = true;
>
> desc = kzalloc(desc_size, GFP_KERNEL);
> if (!desc)
> @@ -69,8 +80,6 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
> * digest we just calculated.
> */
> if (sinfo->authattrs) {
> - u8 tag;
> -
> if (!sinfo->msgdigest) {
> pr_warn("Sig %u: No messageDigest\n", sinfo->index);
> ret = -EKEYREJECTED;
> @@ -96,21 +105,25 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
> * as the contents of the digest instead. Note that we need to
> * convert the attributes from a CONT.0 into a SET before we
> * hash it.
> + *
> + * However, for certain algorithms, such as ML-DSA, the digest
> + * is integrated into the signing algorithm. In such a case,
> + * we copy the authattrs, modifying the tag type, and set that
> + * as the digest.
> */
> - memset(sig->m, 0, sig->m_size);
> -
> -
> - ret = crypto_shash_init(desc);
> - if (ret < 0)
> - goto error;
> - tag = ASN1_CONS_BIT | ASN1_SET;
> - ret = crypto_shash_update(desc, &tag, 1);
> - if (ret < 0)
> - goto error;
> - ret = crypto_shash_finup(desc, sinfo->authattrs,
> - sinfo->authattrs_len, sig->m);
> - if (ret < 0)
> - goto error;
> + memcpy(sig->m, sinfo->authattrs, sinfo->authattrs_len);
> + sig->m[0] = ASN1_CONS_BIT | ASN1_SET;
> +
> + if (sig->algo_takes_data) {
> + sig->m_size = sinfo->authattrs_len;
> + ret = 0;
> + } else {
> + ret = crypto_shash_digest(desc, sig->m,
> + sinfo->authattrs_len,
> + sig->m);
> + if (ret < 0)
> + goto error;
> + }
> pr_devel("AADigest = [%*ph]\n", 8, sig->m);
> }
>
> @@ -137,6 +150,11 @@ int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
> ret = pkcs7_digest(pkcs7, sinfo);
> if (ret)
> return ret;
> + if (!sinfo->sig->m_free) {
> + pr_notice_once("%s: No digest available\n", __func__);
> + return -EINVAL; /* TODO: MLDSA doesn't necessarily calculate an
> + * intermediate digest. */
Is this logic going to change in the foreseeable future?
> + }
>
> *buf = sinfo->sig->m;
> *len = sinfo->sig->m_size;
> diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
> index f4ec126121b3..a5ac7a53b670 100644
> --- a/crypto/asymmetric_keys/signature.c
> +++ b/crypto/asymmetric_keys/signature.c
> @@ -28,7 +28,8 @@ void public_key_signature_free(struct public_key_signature *sig)
> for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
> kfree(sig->auth_ids[i]);
> kfree(sig->s);
> - kfree(sig->m);
> + if (sig->m_free)
> + kfree(sig->m);
> kfree(sig);
> }
> }
> diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
> index 3854f7ae4ed0..27b4fea37845 100644
> --- a/crypto/asymmetric_keys/x509_public_key.c
> +++ b/crypto/asymmetric_keys/x509_public_key.c
> @@ -50,6 +50,14 @@ int x509_get_sig_params(struct x509_certificate *cert)
>
> sig->s_size = cert->raw_sig_size;
>
> + if (sig->algo_takes_data) {
> + /* The signature algorithm does whatever passes for hashing. */
> + sig->m = (u8 *)cert->tbs;
> + sig->m_size = cert->tbs_size;
> + sig->m_free = false;
> + goto out;
> + }
> +
> /* Allocate the hashing algorithm we're going to need and find out how
> * big the hash operational data will be.
> */
> @@ -69,6 +77,7 @@ int x509_get_sig_params(struct x509_certificate *cert)
> sig->m = kmalloc(sig->m_size, GFP_KERNEL);
> if (!sig->m)
> goto error;
> + sig->m_free = true;
>
> desc = kzalloc(desc_size, GFP_KERNEL);
> if (!desc)
> @@ -84,6 +93,7 @@ int x509_get_sig_params(struct x509_certificate *cert)
> kfree(desc);
> error:
> crypto_free_shash(tfm);
> +out:
> pr_devel("<==%s() = %d\n", __func__, ret);
> return ret;
> }
> diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
> index bd38ba4d217d..4c5199b20338 100644
> --- a/include/crypto/public_key.h
> +++ b/include/crypto/public_key.h
> @@ -46,6 +46,8 @@ struct public_key_signature {
> u8 *m; /* Message data to pass to verifier */
> u32 s_size; /* Number of bytes in signature */
> u32 m_size; /* Number of bytes in ->m */
> + bool m_free; /* T if ->m needs freeing */
> + bool algo_takes_data; /* T if public key algo operates on data, not a hash */
> const char *pkey_algo;
> const char *hash_algo;
> const char *encoding;
>
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v16 5/7] pkcs7, x509: Add ML-DSA support
From: Jarkko Sakkinen @ 2026-02-03 0:30 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, Ignat Korchagin, Herbert Xu, Eric Biggers,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Jason A . Donenfeld, Ard Biesheuvel, Stephan Mueller,
linux-crypto, keyrings, linux-modules, linux-kernel
In-Reply-To: <20260202170216.2467036-6-dhowells@redhat.com>
On Mon, Feb 02, 2026 at 05:02:10PM +0000, David Howells wrote:
> Add support for ML-DSA keys and signatures to the CMS/PKCS#7 and X.509
> implementations. ML-DSA-44, -65 and -87 are all supported. For X.509
> certificates, the TBSCertificate is required to be signed directly; for
> CMS, direct signing of the data is preferred, though use of SHA512 (and
> only that) as an intermediate hash of the content is permitted with
> signedAttrs.
>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Lukas Wunner <lukas@wunner.de>
> cc: Ignat Korchagin <ignat@cloudflare.com>
> cc: Stephan Mueller <smueller@chronox.de>
> cc: Eric Biggers <ebiggers@kernel.org>
> cc: Herbert Xu <herbert@gondor.apana.org.au>
> cc: keyrings@vger.kernel.org
> cc: linux-crypto@vger.kernel.org
> ---
> crypto/asymmetric_keys/pkcs7_parser.c | 24 +++++++++++++++++++-
> crypto/asymmetric_keys/public_key.c | 10 +++++++++
> crypto/asymmetric_keys/x509_cert_parser.c | 27 ++++++++++++++++++++++-
> include/linux/oid_registry.h | 5 +++++
> 4 files changed, 64 insertions(+), 2 deletions(-)
>
> diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
> index 3cdbab3b9f50..594a8f1d9dfb 100644
> --- a/crypto/asymmetric_keys/pkcs7_parser.c
> +++ b/crypto/asymmetric_keys/pkcs7_parser.c
> @@ -95,11 +95,18 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
> if (sinfo->authattrs) {
> want = true;
> msg->have_authattrs = true;
> + } else if (sinfo->sig->algo_takes_data) {
> + sinfo->sig->hash_algo = "none";
> }
>
> - for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next)
> + for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next) {
> if (!!sinfo->authattrs != want)
> goto inconsistent;
> +
> + if (!sinfo->authattrs &&
> + sinfo->sig->algo_takes_data)
> + sinfo->sig->hash_algo = "none";
> + }
> return 0;
>
> inconsistent:
> @@ -297,6 +304,21 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
> ctx->sinfo->sig->pkey_algo = "ecrdsa";
> ctx->sinfo->sig->encoding = "raw";
> break;
> + case OID_id_ml_dsa_44:
> + ctx->sinfo->sig->pkey_algo = "mldsa44";
> + ctx->sinfo->sig->encoding = "raw";
> + ctx->sinfo->sig->algo_takes_data = true;
> + break;
> + case OID_id_ml_dsa_65:
> + ctx->sinfo->sig->pkey_algo = "mldsa65";
> + ctx->sinfo->sig->encoding = "raw";
> + ctx->sinfo->sig->algo_takes_data = true;
> + break;
> + case OID_id_ml_dsa_87:
> + ctx->sinfo->sig->pkey_algo = "mldsa87";
> + ctx->sinfo->sig->encoding = "raw";
> + ctx->sinfo->sig->algo_takes_data = true;
> + break;
> default:
> printk("Unsupported pkey algo: %u\n", ctx->last_oid);
> return -ENOPKG;
> diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
> index a46356e0c08b..09a0b83d5d77 100644
> --- a/crypto/asymmetric_keys/public_key.c
> +++ b/crypto/asymmetric_keys/public_key.c
> @@ -142,6 +142,16 @@ software_key_determine_akcipher(const struct public_key *pkey,
> if (strcmp(hash_algo, "streebog256") != 0 &&
> strcmp(hash_algo, "streebog512") != 0)
> return -EINVAL;
> + } else if (strcmp(pkey->pkey_algo, "mldsa44") == 0 ||
> + strcmp(pkey->pkey_algo, "mldsa65") == 0 ||
> + strcmp(pkey->pkey_algo, "mldsa87") == 0) {
> + if (strcmp(encoding, "raw") != 0)
> + return -EINVAL;
> + if (!hash_algo)
> + return -EINVAL;
> + if (strcmp(hash_algo, "none") != 0 &&
> + strcmp(hash_algo, "sha512") != 0)
> + return -EINVAL;
> } else {
> /* Unknown public key algorithm */
> return -ENOPKG;
> diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
> index b37cae914987..2fe094f5caf3 100644
> --- a/crypto/asymmetric_keys/x509_cert_parser.c
> +++ b/crypto/asymmetric_keys/x509_cert_parser.c
> @@ -257,6 +257,15 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
> case OID_gost2012Signature512:
> ctx->cert->sig->hash_algo = "streebog512";
> goto ecrdsa;
> + case OID_id_ml_dsa_44:
> + ctx->cert->sig->pkey_algo = "mldsa44";
> + goto ml_dsa;
> + case OID_id_ml_dsa_65:
> + ctx->cert->sig->pkey_algo = "mldsa65";
> + goto ml_dsa;
> + case OID_id_ml_dsa_87:
> + ctx->cert->sig->pkey_algo = "mldsa87";
> + goto ml_dsa;
> }
>
> rsa_pkcs1:
> @@ -274,6 +283,12 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
> ctx->cert->sig->encoding = "x962";
> ctx->sig_algo = ctx->last_oid;
> return 0;
> +ml_dsa:
> + ctx->cert->sig->algo_takes_data = true;
> + ctx->cert->sig->hash_algo = "none";
> + ctx->cert->sig->encoding = "raw";
> + ctx->sig_algo = ctx->last_oid;
> + return 0;
> }
>
> /*
> @@ -300,7 +315,8 @@ int x509_note_signature(void *context, size_t hdrlen,
>
> if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
> strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 ||
> - strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0) {
> + strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0 ||
> + strncmp(ctx->cert->sig->pkey_algo, "mldsa", 5) == 0) {
> /* Discard the BIT STRING metadata */
> if (vlen < 1 || *(const u8 *)value != 0)
> return -EBADMSG;
> @@ -524,6 +540,15 @@ int x509_extract_key_data(void *context, size_t hdrlen,
> return -ENOPKG;
> }
> break;
> + case OID_id_ml_dsa_44:
> + ctx->cert->pub->pkey_algo = "mldsa44";
> + break;
> + case OID_id_ml_dsa_65:
> + ctx->cert->pub->pkey_algo = "mldsa65";
> + break;
> + case OID_id_ml_dsa_87:
> + ctx->cert->pub->pkey_algo = "mldsa87";
> + break;
> default:
> return -ENOPKG;
> }
> diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
> index 6de479ebbe5d..ebce402854de 100644
> --- a/include/linux/oid_registry.h
> +++ b/include/linux/oid_registry.h
> @@ -145,6 +145,11 @@ enum OID {
> OID_id_rsassa_pkcs1_v1_5_with_sha3_384, /* 2.16.840.1.101.3.4.3.15 */
> OID_id_rsassa_pkcs1_v1_5_with_sha3_512, /* 2.16.840.1.101.3.4.3.16 */
>
> + /* NIST FIPS-204 ML-DSA */
> + OID_id_ml_dsa_44, /* 2.16.840.1.101.3.4.3.17 */
> + OID_id_ml_dsa_65, /* 2.16.840.1.101.3.4.3.18 */
> + OID_id_ml_dsa_87, /* 2.16.840.1.101.3.4.3.19 */
> +
> OID__NR
> };
>
>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v16 7/7] pkcs7: Allow authenticatedAttributes for ML-DSA
From: Jarkko Sakkinen @ 2026-02-03 0:35 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, Ignat Korchagin, Herbert Xu, Eric Biggers,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Jason A . Donenfeld, Ard Biesheuvel, Stephan Mueller,
linux-crypto, keyrings, linux-modules, linux-kernel
In-Reply-To: <20260202170216.2467036-8-dhowells@redhat.com>
On Mon, Feb 02, 2026 at 05:02:12PM +0000, David Howells wrote:
> Allow the rejection of authenticatedAttributes in PKCS#7 (signedAttrs in
> CMS) to be waived in the kernel config for ML-DSA when used for module
> signing. This reflects the issue that openssl < 4.0 cannot do this and
> openssl-4 has not yet been released.
>
> This does not permit RSA, ECDSA or ECRDSA to be so waived (behaviour
> unchanged).
>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Lukas Wunner <lukas@wunner.de>
> cc: Ignat Korchagin <ignat@cloudflare.com>
> cc: Jarkko Sakkinen <jarkko@kernel.org>
> cc: Stephan Mueller <smueller@chronox.de>
> cc: Eric Biggers <ebiggers@kernel.org>
> cc: Herbert Xu <herbert@gondor.apana.org.au>
> cc: keyrings@vger.kernel.org
> cc: linux-crypto@vger.kernel.org
> ---
> crypto/asymmetric_keys/Kconfig | 11 +++++++++++
> crypto/asymmetric_keys/pkcs7_parser.c | 8 ++++++++
> crypto/asymmetric_keys/pkcs7_parser.h | 3 +++
> crypto/asymmetric_keys/pkcs7_verify.c | 6 ++++++
> 4 files changed, 28 insertions(+)
>
> diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
> index e1345b8f39f1..1dae2232fe9a 100644
> --- a/crypto/asymmetric_keys/Kconfig
> +++ b/crypto/asymmetric_keys/Kconfig
> @@ -53,6 +53,17 @@ config PKCS7_MESSAGE_PARSER
> This option provides support for parsing PKCS#7 format messages for
> signature data and provides the ability to verify the signature.
>
> +config PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
> + bool "Waive rejection of authenticatedAttributes for ML-DSA"
> + depends on PKCS7_MESSAGE_PARSER
> + depends on CRYPTO_MLDSA
> + help
> + Due to use of CMS_NOATTR with ML-DSA not being supported in
> + OpenSSL < 4.0 (and thus any released version), enabling this
> + allows authenticatedAttributes to be used with ML-DSA for
> + module signing. Use of authenticatedAttributes in this
> + context is normally rejected.
> +
> config PKCS7_TEST_KEY
> tristate "PKCS#7 testing key type"
> depends on SYSTEM_DATA_VERIFICATION
> diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
> index 594a8f1d9dfb..db1c90ca6fc1 100644
> --- a/crypto/asymmetric_keys/pkcs7_parser.c
> +++ b/crypto/asymmetric_keys/pkcs7_parser.c
> @@ -92,9 +92,17 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
> if (!sinfo)
> goto inconsistent;
>
> +#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
> + msg->authattrs_rej_waivable = true;
> +#endif
> +
> if (sinfo->authattrs) {
> want = true;
> msg->have_authattrs = true;
> +#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
> + if (strncmp(sinfo->sig->pkey_algo, "mldsa", 5) != 0)
> + msg->authattrs_rej_waivable = false;
> +#endif
> } else if (sinfo->sig->algo_takes_data) {
> sinfo->sig->hash_algo = "none";
> }
> diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
> index e17f7ce4fb43..6ef9f335bb17 100644
> --- a/crypto/asymmetric_keys/pkcs7_parser.h
> +++ b/crypto/asymmetric_keys/pkcs7_parser.h
> @@ -55,6 +55,9 @@ struct pkcs7_message {
> struct pkcs7_signed_info *signed_infos;
> u8 version; /* Version of cert (1 -> PKCS#7 or CMS; 3 -> CMS) */
> bool have_authattrs; /* T if have authattrs */
> +#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
> + bool authattrs_rej_waivable; /* T if authatts rejection can be waived */
> +#endif
>
> /* Content Data (or NULL) */
> enum OID data_type; /* Type of Data */
> diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
> index 06abb9838f95..519eecfe6778 100644
> --- a/crypto/asymmetric_keys/pkcs7_verify.c
> +++ b/crypto/asymmetric_keys/pkcs7_verify.c
> @@ -425,6 +425,12 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
> return -EKEYREJECTED;
> }
> if (pkcs7->have_authattrs) {
> +#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
> + if (pkcs7->authattrs_rej_waivable) {
> + pr_warn("Waived invalid module sig (has authattrs)\n");
> + break;
> + }
> +#endif
> pr_warn("Invalid module sig (has authattrs)\n");
> return -EKEYREJECTED;
> }
>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
From: James Bottomley @ 2026-02-03 8:18 UTC (permalink / raw)
To: David Howells, Mihai-Drosi Câju
Cc: linux, arnd, arnout, atomlin, bigeasy, chleroy, christian, corbet,
coxu, da.gomez, da.gomez, dmitry.kasatkin, eric.snowberg,
f.gruenbichler, jmorris, kpcyrd, linux-arch, linux-doc,
linux-integrity, linux-kbuild, linux-kernel, linux-modules,
linux-security-module, linuxppc-dev, lkp, maddy, mattia, mcgrof,
mpe, nathan, naveen, nicolas.bouchinet, nicolas.schier, npiggin,
nsc, paul, petr.pavlu, roberto.sassu, samitolvanen, serge,
xiujianfeng, zohar
In-Reply-To: <2316630.1769965788@warthog.procyon.org.uk>
On Sun, 2026-02-01 at 17:09 +0000, David Howells wrote:
> Mihai-Drosi Câju <mcaju95@gmail.com> wrote:
>
> > > The current signature-based module integrity checking has some
> > > drawbacks
> > in combination with reproducible builds. Either the module signing
> > key is generated at build time, which makes the build
> > unreproducible, or a static signing key is used, which precludes
> > rebuilds by third parties and makes the whole build and packaging
> > process much more complicated.
>
> There is another issue too: If you have a static private key that you
> use to sign modules (and probably other things), someone will likely
> give you a GPL request to get it.
The SFC just lost that exact point in the Vizio trial, so I think
you're wrong on this under US law at least. There's no general ability
under GPLv2 to demand long lived signing keys.
Regards,
James
^ permalink raw reply
* Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
From: David Howells @ 2026-02-03 8:22 UTC (permalink / raw)
To: James Bottomley
Cc: dhowells, Mihai-Drosi Câju, linux, arnd, arnout, atomlin,
bigeasy, chleroy, christian, corbet, coxu, da.gomez, da.gomez,
dmitry.kasatkin, eric.snowberg, f.gruenbichler, jmorris, kpcyrd,
linux-arch, linux-doc, linux-integrity, linux-kbuild,
linux-kernel, linux-modules, linux-security-module, linuxppc-dev,
lkp, maddy, mattia, mcgrof, mpe, nathan, naveen,
nicolas.bouchinet, nicolas.schier, npiggin, nsc, paul, petr.pavlu,
roberto.sassu, samitolvanen, serge, xiujianfeng, zohar
In-Reply-To: <8b12f1d28d3859467c3b5f6bc352038ce7627e54.camel@HansenPartnership.com>
James Bottomley <James.Bottomley@HansenPartnership.com> wrote:
> > There is another issue too: If you have a static private key that you
> > use to sign modules (and probably other things), someone will likely
> > give you a GPL request to get it.
>
> The SFC just lost that exact point in the Vizio trial, so I think
> you're wrong on this under US law at least. There's no general ability
> under GPLv2 to demand long lived signing keys.
Cool :-). I just know that I've been sent GPL requests for kernel keys.
David
^ permalink raw reply
* Re: [PATCH v16 4/7] pkcs7: Allow the signing algo to do whatever digestion it wants itself
From: David Howells @ 2026-02-03 8:37 UTC (permalink / raw)
To: Jarkko Sakkinen
Cc: dhowells, Lukas Wunner, Ignat Korchagin, Herbert Xu, Eric Biggers,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Jason A . Donenfeld, Ard Biesheuvel, Stephan Mueller,
linux-crypto, keyrings, linux-modules, linux-kernel
In-Reply-To: <aYFBbGmMTszT3ZRb@kernel.org>
Jarkko Sakkinen <jarkko@kernel.org> wrote:
> > + if (!sinfo->sig->m_free) {
> > + pr_notice_once("%s: No digest available\n", __func__);
> > + return -EINVAL; /* TODO: MLDSA doesn't necessarily calculate an
> > + * intermediate digest. */
>
> Is this logic going to change in the foreseeable future?
This is only used by IMA to retrieve an intermediate digest, so something will
need to be fixed to support use of ML-DSA in IMA, but I don't know what yet.
It doesn't, however, preclude the use of the rest of the code for module or
kexec signature verification, so I think it's reasonable enough just to emit a
warning and return an error here for now.
David
^ permalink raw reply
* Re: [PATCH v15 6/7] modsign: Enable ML-DSA module signing
From: Venkat @ 2026-02-03 9:42 UTC (permalink / raw)
To: David Howells
Cc: Michael Kelley, Sami Tolvanen, Lukas Wunner, Ignat Korchagin,
Jarkko Sakkinen, Herbert Xu, Eric Biggers, Luis Chamberlain,
Petr Pavlu, Daniel Gomez, Jason A . Donenfeld, Ard Biesheuvel,
Stephan Mueller, linux-crypto@vger.kernel.org,
keyrings@vger.kernel.org, linux-modules@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <2416273.1770032906@warthog.procyon.org.uk>
> On 2 Feb 2026, at 5:18 PM, David Howells <dhowells@redhat.com> wrote:
>
> Michael Kelley <mhklinux@outlook.com> wrote:
>
>> Pardon my ignorance of the signing details, but I don't see an indication
>> of having selected PKCS#7 with SHA1 in my .config. What am I looking for?
>
> Actually, if you have openssl >= 1.0.0 then it sign-file will be built to use
> CMS rather than PKCS#7, and will use the configured hash algo, so you can
> ignore this.
>
>> The symbols CMS_NO_SIGNING_TIME,
>
> I can probably just not add that.
>
>> EVP_PKEY_is_a()
>
> I guess I can probably make this contingent on >= 3.0.0.
>
>> and OPENSSL_VERSION_MAJOR don't exist in the include/openssl/* files for
>> that old version.
>
> I should probably use OPENSSL_VERSION_NUMBER instead - though we already use
> it for selecting #includes (I guess #if doesn't complain).
>
> Do the attached changes work for you?
>
> David
> ---
> diff --git a/scripts/sign-file.c b/scripts/sign-file.c
> index 547b97097230..78276b15ab23 100644
> --- a/scripts/sign-file.c
> +++ b/scripts/sign-file.c
> @@ -27,7 +27,7 @@
> #include <openssl/evp.h>
> #include <openssl/pem.h>
> #include <openssl/err.h>
> -#if OPENSSL_VERSION_MAJOR >= 3
> +#if OPENSSL_VERSION_NUMBER >= 0x30000000L
> # define USE_PKCS11_PROVIDER
> # include <openssl/provider.h>
> # include <openssl/store.h>
> @@ -323,18 +323,21 @@ int main(int argc, char **argv)
> CMS_DETACHED |
> CMS_STREAM |
> CMS_NOSMIMECAP |
> +#ifdef CMS_NO_SIGNING_TIME
> CMS_NO_SIGNING_TIME |
> +#endif
> use_keyid;
>
> - if ((EVP_PKEY_is_a(private_key, "ML-DSA-44") ||
> - EVP_PKEY_is_a(private_key, "ML-DSA-65") ||
> - EVP_PKEY_is_a(private_key, "ML-DSA-87")) &&
> - OPENSSL_VERSION_MAJOR < 4) {
> +#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_VERSION_NUMBER < 0x40000000L
> + if (EVP_PKEY_is_a(private_key, "ML-DSA-44") ||
> + EVP_PKEY_is_a(private_key, "ML-DSA-65") ||
> + EVP_PKEY_is_a(private_key, "ML-DSA-87")) {
> /* ML-DSA + CMS_NOATTR is not supported in openssl-3.5
> * and before.
> */
> use_signed_attrs = 0;
> }
> +#endif
>
> flags |= use_signed_attrs;
>
Tested this, and build is successful. Please add below tag.
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Regards,
Venkat.
^ permalink raw reply
* Re: [PATCH v3 0/2] Improve handling of the __klp_{objects,funcs} sections in modules
From: Miroslav Benes @ 2026-02-03 10:24 UTC (permalink / raw)
To: Petr Pavlu
Cc: Josh Poimboeuf, Jiri Kosina, Petr Mladek, Joe Lawrence,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, Aaron Tomlin,
Peter Zijlstra, live-patching, linux-modules, linux-kernel
In-Reply-To: <20260123102825.3521961-1-petr.pavlu@suse.com>
On Fri, 23 Jan 2026, Petr Pavlu wrote:
> Changes since v2 [1]:
> - Generalize the helper function that locates __klp_objects in a module
> to allow it to find any data in other sections as well.
>
> Changes since v1 [2]:
> - Generalize the helper function that locates __klp_objects in a module
> to allow it to find objects in other sections as well.
>
> [1] https://lore.kernel.org/linux-modules/20260121082842.3050453-1-petr.pavlu@suse.com/
> [2] https://lore.kernel.org/linux-modules/20260114123056.2045816-1-petr.pavlu@suse.com/
>
> Petr Pavlu (2):
> livepatch: Fix having __klp_objects relics in non-livepatch modules
> livepatch: Free klp_{object,func}_ext data after initialization
>
> include/linux/livepatch.h | 3 +++
> kernel/livepatch/core.c | 19 +++++++++++++++++++
> scripts/livepatch/init.c | 20 +++++++++-----------
> scripts/module.lds.S | 9 ++-------
> tools/objtool/check.c | 2 +-
> tools/objtool/include/objtool/klp.h | 10 +++++-----
> tools/objtool/klp-diff.c | 2 +-
> 7 files changed, 40 insertions(+), 25 deletions(-)
>
>
> base-commit: 0f61b1860cc3f52aef9036d7235ed1f017632193
Acked-by: Miroslav Benes <mbenes@suse.cz>
Thank you,
M
^ permalink raw reply
* Re: [PATCH v4 15/17] module: Introduce hash-based integrity checking
From: Petr Pavlu @ 2026-02-03 12:19 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Sami Tolvanen,
Daniel Gomez, Paul Moore, James Morris, Serge E. Hallyn,
Jonathan Corbet, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Nicolas Schier, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Schier,
Nicolas Bouchinet, Xiu Jianfeng, Fabian Grünbichler,
Arnout Engelen, Mattia Rizzolo, kpcyrd, Christian Heusel,
Câju Mihai-Drosi, Sebastian Andrzej Siewior, linux-kbuild,
linux-kernel, linux-arch, linux-modules, linux-security-module,
linux-doc, linuxppc-dev, linux-integrity
In-Reply-To: <20260113-module-hashes-v4-15-0b932db9b56b@weissschuh.net>
On 1/13/26 1:28 PM, Thomas Weißschuh wrote:
> The current signature-based module integrity checking has some drawbacks
> in combination with reproducible builds. Either the module signing key
> is generated at build time, which makes the build unreproducible, or a
> static signing key is used, which precludes rebuilds by third parties
> and makes the whole build and packaging process much more complicated.
>
> The goal is to reach bit-for-bit reproducibility. Excluding certain
> parts of the build output from the reproducibility analysis would be
> error-prone and force each downstream consumer to introduce new tooling.
>
> Introduce a new mechanism to ensure only well-known modules are loaded
> by embedding a merkle tree root of all modules built as part of the full
> kernel build into vmlinux.
>
> Non-builtin modules can be validated as before through signatures.
>
> Normally the .ko module files depend on a fully built vmlinux to be
> available for modpost validation and BTF generation. With
> CONFIG_MODULE_HASHES, vmlinux now depends on the modules
> to build a merkle tree. This introduces a dependency cycle which is
> impossible to satisfy. Work around this by building the modules during
> link-vmlinux.sh, after vmlinux is complete enough for modpost and BTF
> but before the final module hashes are
>
> The PKCS7 format which is used for regular module signatures can not
> represent Merkle proofs, so a new kind of module signature is
> introduced. As this signature type is only ever used for builtin
> modules, no compatibility issues can arise.
Nit: The description uses the term "builtin modules" in a misleading
way. Typically, "builtin modules" refers to modules that are linked
directly into vmlinux. However, this text uses the term to refer to
loadable modules that are built together with the main kernel image,
which is something different.
> diff --git a/scripts/modules-merkle-tree.c b/scripts/modules-merkle-tree.c
> new file mode 100644
> index 000000000000..a6ec0e21213b
> --- /dev/null
> +++ b/scripts/modules-merkle-tree.c
> @@ -0,0 +1,467 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Compute hashes for modules files and build a merkle tree.
> + *
> + * Copyright (C) 2025 Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
> + * Copyright (C) 2025 Thomas Weißschuh <linux@weissschuh.net>
> + *
> + */
> +#define _GNU_SOURCE 1
> +#include <arpa/inet.h>
> +#include <err.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdbool.h>
> +#include <stdlib.h>
> +
> +#include <sys/stat.h>
> +#include <sys/mman.h>
> +
> +#include <openssl/evp.h>
> +#include <openssl/err.h>
> +
> +#include "ssl-common.h"
> +
> +static int hash_size;
> +static EVP_MD_CTX *ctx;
> +
> +struct module_signature {
> + uint8_t algo; /* Public-key crypto algorithm [0] */
> + uint8_t hash; /* Digest algorithm [0] */
> + uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */
> + uint8_t signer_len; /* Length of signer's name [0] */
> + uint8_t key_id_len; /* Length of key identifier [0] */
> + uint8_t __pad[3];
> + uint32_t sig_len; /* Length of signature data */
> +};
> +
> +#define PKEY_ID_MERKLE 3
> +
> +static const char magic_number[] = "~Module signature appended~\n";
It might make sense to put these common structures into a file under
scripts/include/ so they can be shared by both scripts/sign-file.c and
scripts/modules-merkle-tree.c.
> +
> +struct file_entry {
> + char *name;
> + unsigned int pos;
> + unsigned char hash[EVP_MAX_MD_SIZE];
> +};
> +
> +static struct file_entry *fh_list;
> +static size_t num_files;
> +
> +struct leaf_hash {
> + unsigned char hash[EVP_MAX_MD_SIZE];
> +};
> +
> +struct mtree {
> + struct leaf_hash **l;
> + unsigned int *entries;
> + unsigned int levels;
> +};
> +
> +static inline void *xcalloc(size_t n, size_t size)
> +{
> + void *p;
> +
> + p = calloc(n, size);
> + if (!p)
> + errx(1, "Memory allocation failed");
> +
> + return p;
> +}
> +
> +static void *xmalloc(size_t size)
> +{
> + void *p;
> +
> + p = malloc(size);
> + if (!p)
> + errx(1, "Memory allocation failed");
> +
> + return p;
> +}
> +
> +static inline void *xreallocarray(void *oldp, size_t n, size_t size)
> +{
> + void *p;
> +
> + p = reallocarray(oldp, n, size);
> + if (!p)
> + errx(1, "Memory allocation failed");
> +
> + return p;
> +}
> +
> +static inline char *xasprintf(const char *fmt, ...)
> +{
> + va_list ap;
> + char *strp;
> + int ret;
> +
> + va_start(ap, fmt);
> + ret = vasprintf(&strp, fmt, ap);
> + va_end(ap);
> + if (ret == -1)
> + err(1, "Memory allocation failed");
> +
> + return strp;
> +}
I believe it is preferable to use xmalloc() and related functions from
scripts/include/xalloc.h, instead of defining your own variants. If
something is missing in xalloc.h, it can be extended.
> +
> +static unsigned int get_pow2(unsigned int val)
> +{
> + return 31 - __builtin_clz(val);
> +}
> +
> +static unsigned int roundup_pow2(unsigned int val)
> +{
> + return 1 << (get_pow2(val - 1) + 1);
> +}
> +
> +static unsigned int log2_roundup(unsigned int val)
> +{
> + return get_pow2(roundup_pow2(val));
> +}
In the edge case when the kernel is built with only one module, the code
calls log2_roundup(1) -> roundup_pow2(1) -> get_pow2(0) ->
__builtin_clz(0). The return value of __builtin_clz() is undefined if
the input is zero.
> +
> +static void hash_data(void *p, unsigned int pos, size_t size, void *ret_hash)
> +{
> + unsigned char magic = 0x01;
> + unsigned int pos_be;
> +
> + pos_be = htonl(pos);
> +
> + ERR(EVP_DigestInit_ex(ctx, NULL, NULL) != 1, "EVP_DigestInit_ex()");
> + ERR(EVP_DigestUpdate(ctx, &magic, sizeof(magic)) != 1, "EVP_DigestUpdate(magic)");
> + ERR(EVP_DigestUpdate(ctx, &pos_be, sizeof(pos_be)) != 1, "EVP_DigestUpdate(pos)");
> + ERR(EVP_DigestUpdate(ctx, p, size) != 1, "EVP_DigestUpdate(data)");
> + ERR(EVP_DigestFinal_ex(ctx, ret_hash, NULL) != 1, "EVP_DigestFinal_ex()");
> +}
> +
> +static void hash_entry(void *left, void *right, void *ret_hash)
> +{
> + int hash_size = EVP_MD_CTX_get_size_ex(ctx);
Nit: The local variable hash_size can be removed, as the static variable
with the same name should hold the same value.
> + unsigned char magic = 0x02;
> +
> + ERR(EVP_DigestInit_ex(ctx, NULL, NULL) != 1, "EVP_DigestInit_ex()");
> + ERR(EVP_DigestUpdate(ctx, &magic, sizeof(magic)) != 1, "EVP_DigestUpdate(magic)");
> + ERR(EVP_DigestUpdate(ctx, left, hash_size) != 1, "EVP_DigestUpdate(left)");
> + ERR(EVP_DigestUpdate(ctx, right, hash_size) != 1, "EVP_DigestUpdate(right)");
> + ERR(EVP_DigestFinal_ex(ctx, ret_hash, NULL) != 1, "EVP_DigestFinal_ex()");
> +}
> +
> +static void hash_file(struct file_entry *fe)
> +{
> + struct stat sb;
> + int fd, ret;
> + void *mem;
> +
> + fd = open(fe->name, O_RDONLY);
> + if (fd < 0)
> + err(1, "Failed to open %s", fe->name);
> +
> + ret = fstat(fd, &sb);
> + if (ret)
> + err(1, "Failed to stat %s", fe->name);
> +
> + mem = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
> + close(fd);
> +
> + if (mem == MAP_FAILED)
> + err(1, "Failed to mmap %s", fe->name);
Nit: The err() call should be moved immediately after mmap(). In theory,
the interleaving close() could change the errno value, resulting in
err() printing a misleading error message.
> +
> + hash_data(mem, fe->pos, sb.st_size, fe->hash);
> +
> + munmap(mem, sb.st_size);
> +}
> +
> +static struct mtree *build_merkle(struct file_entry *fh, size_t num)
> +{
> + struct mtree *mt;
> + unsigned int le;
> +
> + if (!num)
> + return NULL;
> +
> + mt = xmalloc(sizeof(*mt));
> + mt->levels = log2_roundup(num);
> +
> + mt->l = xcalloc(sizeof(*mt->l), mt->levels);
> +
> + mt->entries = xcalloc(sizeof(*mt->entries), mt->levels);
> + le = num / 2;
> + if (num & 1)
> + le++;
> + mt->entries[0] = le;
> + mt->l[0] = xcalloc(sizeof(**mt->l), le);
> +
> + /* First level of pairs */
> + for (unsigned int i = 0; i < num; i += 2) {
> + if (i == num - 1) {
> + /* Odd number of files, no pair. Hash with itself */
> + hash_entry(fh[i].hash, fh[i].hash, mt->l[0][i / 2].hash);
> + } else {
> + hash_entry(fh[i].hash, fh[i + 1].hash, mt->l[0][i / 2].hash);
> + }
> + }
> + for (unsigned int i = 1; i < mt->levels; i++) {
> + int odd = 0;
> +
> + if (le & 1) {
> + le++;
> + odd++;
> + }
> +
> + mt->entries[i] = le / 2;
> + mt->l[i] = xcalloc(sizeof(**mt->l), le);
l[i] is overallocated. It needs only 'le / 2' entries.
> +
> + for (unsigned int n = 0; n < le; n += 2) {
> + if (n == le - 2 && odd) {
> + /* Odd number of pairs, no pair. Hash with itself */
> + hash_entry(mt->l[i - 1][n].hash, mt->l[i - 1][n].hash,
> + mt->l[i][n / 2].hash);
> + } else {
> + hash_entry(mt->l[i - 1][n].hash, mt->l[i - 1][n + 1].hash,
> + mt->l[i][n / 2].hash);
> + }
> + }
> + le = mt->entries[i];
Nit: It might be helpful to write both the first-level and other-level
loops in the same style to make them easier to understand, perhaps by
clearly separating the number of entries at each level. I suggest
something like the following:
static struct mtree *build_merkle(struct file_entry *fh, size_t num_files)
{
struct mtree *mt;
unsigned int num_cur_le, num_prev_le;
if (!num_files)
return NULL;
mt = xmalloc(sizeof(*mt));
mt->levels = log2_roundup(num_files);
mt->l = xcalloc(sizeof(*mt->l), mt->levels);
mt->entries = xcalloc(sizeof(*mt->entries), mt->levels);
num_cur_le = (num_files + 1) / 2;
mt->entries[0] = num_cur_le;
mt->l[0] = xcalloc(sizeof(**mt->l), num_cur_le);
/* First level of pairs */
for (unsigned int i = 0; i < num_files; i += 2) {
/* Hash the pair, or the last file with itself if it's odd. */
void *right = i + 1 < num_files ? fh[i + 1].hash : fh[i].hash;
hash_entry(fh[i].hash, right, mt->l[0][i / 2].hash);
}
for (unsigned int i = 1; i < mt->levels; i++) {
num_prev_le = num_cur_le;
num_cur_le = (num_prev_le + 1) / 2;
mt->entries[i] = num_cur_le;
mt->l[i] = xcalloc(sizeof(**mt->l), num_cur_le);
for (unsigned int n = 0; n < num_prev_le; n += 2) {
/* Hash the pair, or the last with itself if it's odd. */
void *right = n + 1 < num_prev_le ?
mt->l[i - 1][n + 1].hash :
mt->l[i - 1][n].hash;
hash_entry(mt->l[i - 1][n].hash, right,
mt->l[i][n / 2].hash);
}
}
return mt;
}
> + }
> + return mt;
> +}
> +
> +static void free_mtree(struct mtree *mt)
> +{
> + if (!mt)
> + return;
> +
> + for (unsigned int i = 0; i < mt->levels; i++)
> + free(mt->l[i]);
> +
> + free(mt->l);
> + free(mt->entries);
> + free(mt);
> +}
> +
> +static void write_be_int(int fd, unsigned int v)
> +{
> + unsigned int be_val = htonl(v);
> +
> + if (write(fd, &be_val, sizeof(be_val)) != sizeof(be_val))
> + err(1, "Failed writing to file");
> +}
> +
> +static void write_hash(int fd, const void *h)
> +{
> + ssize_t wr;
> +
> + wr = write(fd, h, hash_size);
> + if (wr != hash_size)
> + err(1, "Failed writing to file");
> +}
Nit: This could be
if (write(fd, h, hash_size) != hash_size)
to keep the style of write_be_int() and write_hash() consistent.
> +
> +static void build_proof(struct mtree *mt, unsigned int n, int fd)
> +{
> + unsigned char cur[EVP_MAX_MD_SIZE];
> + unsigned char tmp[EVP_MAX_MD_SIZE];
> + struct file_entry *fe, *fe_sib;
> +
> + fe = &fh_list[n];
> +
> + if ((n & 1) == 0) {
> + /* No pair, hash with itself */
> + if (n + 1 == num_files)
> + fe_sib = fe;
> + else
> + fe_sib = &fh_list[n + 1];
> + } else {
> + fe_sib = &fh_list[n - 1];
> + }
> + /* First comes the node position into the file */
> + write_be_int(fd, n);
> +
> + if ((n & 1) == 0)
> + hash_entry(fe->hash, fe_sib->hash, cur);
> + else
> + hash_entry(fe_sib->hash, fe->hash, cur);
> +
> + /* Next is the sibling hash, followed by hashes in the tree */
> + write_hash(fd, fe_sib->hash);
> +
> + for (unsigned int i = 0; i < mt->levels - 1; i++) {
> + n >>= 1;
> + if ((n & 1) == 0) {
> + void *h;
> +
> + /* No pair, hash with itself */
> + if (n + 1 == mt->entries[i])
> + h = cur;
> + else
> + h = mt->l[i][n + 1].hash;
> +
> + hash_entry(cur, h, tmp);
> + write_hash(fd, h);
> + } else {
> + hash_entry(mt->l[i][n - 1].hash, cur, tmp);
> + write_hash(fd, mt->l[i][n - 1].hash);
> + }
> + memcpy(cur, tmp, hash_size);
> + }
> +
> + /* After all that, the end hash should match the root hash */
> + if (memcmp(cur, mt->l[mt->levels - 1][0].hash, hash_size))
> + errx(1, "hash mismatch");
> +}
> +
> +static void append_module_signature_magic(int fd, unsigned int sig_len)
> +{
> + struct module_signature sig_info = {
> + .id_type = PKEY_ID_MERKLE,
> + .sig_len = htonl(sig_len),
> + };
> +
> + if (write(fd, &sig_info, sizeof(sig_info)) < 0)
> + err(1, "write(sig_info) failed");
> +
> + if (write(fd, &magic_number, sizeof(magic_number) - 1) < 0)
> + err(1, "write(magic_number) failed");
Nit: Checking that the written size exactly matches the size of the
input data would be safer and consistent with other uses of write() in
write_be_int() and write_hash(). Additionally, it would be good to make
the error messages consistent in all cases.
> +}
> +
> +static void write_merkle_root(struct mtree *mt, const char *fp)
> +{
> + char buf[1024];
> + unsigned int levels;
> + unsigned char *h;
> + FILE *f;
> +
> + if (mt) {
> + levels = mt->levels;
> + h = mt->l[mt->levels - 1][0].hash;
> + } else {
> + levels = 0;
> + h = xcalloc(1, hash_size);
> + }
> +
> + f = fopen(fp, "w");
> + if (!f)
> + err(1, "Failed to create %s", buf);
The last parameter to err() should be fp. The buf variable is then
unused and can be removed.
> +
> + fprintf(f, "#include <linux/module_hashes.h>\n\n");
> + fprintf(f, "const struct module_hashes_root module_hashes_root __module_hashes_section = {\n");
> +
> + fprintf(f, "\t.levels = %u,\n", levels);
> + fprintf(f, "\t.hash = {");
> + for (unsigned int i = 0; i < hash_size; i++) {
> + char *space = "";
> +
> + if (!(i % 8))
> + fprintf(f, "\n\t\t");
> +
> + if ((i + 1) % 8)
> + space = " ";
> +
> + fprintf(f, "0x%02x,%s", h[i], space);
> + }
> + fprintf(f, "\n\t},");
> +
> + fprintf(f, "\n};\n");
> + fclose(f);
Is it ok not to check the return values when writing to this output
file? Other code checks that its output was successful.
> +
> + if (!mt)
> + free(h);
> +}
> +
> +static char *xstrdup_replace_suffix(const char *str, const char *new_suffix)
> +{
> + const char *current_suffix;
> + size_t base_len;
> +
> + current_suffix = strchr(str, '.');
It is safer to use strrchr() in case the module path happens to contain
a dot.
> + if (!current_suffix)
> + errx(1, "No existing suffix in '%s'", str);
> +
> + base_len = current_suffix - str;
> +
> + return xasprintf("%.*s%s", (int)base_len, str, new_suffix);
> +}
> +
> +static void read_modules_order(const char *fname, const char *suffix)
> +{
> + char line[PATH_MAX];
<limits.h> should be included at the top to provide the definition of
PATH_MAX.
> + FILE *in;
> +
> + in = fopen(fname, "r");
> + if (!in)
> + err(1, "fopen(%s)", fname);
Nit: The error message could be "Failed to open %s" to maintain
consistency with a similar error in write_merkle_root().
> +
> + while (fgets(line, PATH_MAX, in)) {
> + struct file_entry *entry;
> +
> + fh_list = xreallocarray(fh_list, num_files + 1, sizeof(*fh_list));
It might be useful to not reallocate this array for each file, although
I don't immediately see that it contributes any significant time to the
runtime.
> + entry = &fh_list[num_files];
> +
> + entry->pos = num_files;
> + entry->name = xstrdup_replace_suffix(line, suffix);
> + hash_file(entry);
> +
> + num_files++;
> + }
> +
> + fclose(in);
> +}
> +
> +static __attribute__((noreturn))
> +void format(void)
> +{
> + fprintf(stderr,
> + "Usage: scripts/modules-merkle-tree <root definition>\n");
The usage string should mention the second parameter, which is the
module suffix.
> + exit(2);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + const EVP_MD *hash_evp;
> + struct mtree *mt;
> +
> + if (argc != 3)
> + format();
> +
> + hash_evp = EVP_get_digestbyname("sha256");
> + ERR(!hash_evp, "EVP_get_digestbyname");
> +
> + ctx = EVP_MD_CTX_new();
> + ERR(!ctx, "EVP_MD_CTX_new()");
> +
> + hash_size = EVP_MD_get_size(hash_evp);
> + ERR(hash_size <= 0, "EVP_get_digestbyname");
> +
> + if (EVP_DigestInit_ex(ctx, hash_evp, NULL) != 1)
> + ERR(1, "EVP_DigestInit_ex()");
> +
> + read_modules_order("modules.order", argv[2]);
> +
> + mt = build_merkle(fh_list, num_files);
> + write_merkle_root(mt, argv[1]);
> + for (unsigned int i = 0; i < num_files; i++) {
> + char *signame;
> + int fd;
> +
> + signame = xstrdup_replace_suffix(fh_list[i].name, ".merkle");
> +
> + fd = open(signame, O_WRONLY | O_CREAT | O_TRUNC, 0644);
> + if (fd < 0)
> + err(1, "Can't create %s", signame);
> +
> + build_proof(mt, i, fd);
> + append_module_signature_magic(fd, lseek(fd, 0, SEEK_CUR));
> + close(fd);
The return code of close() should be checked, otherwise it is
meaningless to check the write() calls in
append_module_signature_magic().
> + }
> +
> + free_mtree(mt);
> + for (unsigned int i = 0; i < num_files; i++)
> + free(fh_list[i].name);
> + free(fh_list);
> +
> + EVP_MD_CTX_free(ctx);
> + return 0;
> +}
--
Thanks,
Petr
^ permalink raw reply
* Re: [PATCH v4 08/17] module: Deduplicate signature extraction
From: Thomas Weißschuh @ 2026-02-03 12:41 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Sami Tolvanen,
Daniel Gomez, Paul Moore, James Morris, Serge E. Hallyn,
Jonathan Corbet, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Nicolas Schier, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Schier,
Nicolas Bouchinet, Xiu Jianfeng, Fabian Grünbichler,
Arnout Engelen, Mattia Rizzolo, kpcyrd, Christian Heusel,
Câju Mihai-Drosi, Sebastian Andrzej Siewior, linux-kbuild,
linux-kernel, linux-arch, linux-modules, linux-security-module,
linux-doc, linuxppc-dev, linux-integrity
In-Reply-To: <52cbbccf-d5b6-4a33-b16a-4a09fe5e64d3@suse.com>
On 2026-01-27 16:20:15+0100, Petr Pavlu wrote:
> On 1/13/26 1:28 PM, Thomas Weißschuh wrote:
(...)
> > int module_sig_check(struct load_info *info, int flags)
> > {
> > - int err = -ENODATA;
> > - const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
> > + int err;
> > const char *reason;
> > const void *mod = info->hdr;
> > + size_t sig_len;
> > + const u8 *sig;
> > bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
> > MODULE_INIT_IGNORE_VERMAGIC);
> > - /*
> > - * Do not allow mangled modules as a module with version information
> > - * removed is no longer the module that was signed.
> > - */
> > - if (!mangled_module &&
> > - info->len > markerlen &&
> > - memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
> > - /* We truncate the module to discard the signature */
> > - info->len -= markerlen;
> > - err = mod_verify_sig(mod, info);
> > +
> > + err = mod_split_sig(info->hdr, &info->len, mangled_module, &sig_len, &sig, "module");
> > + if (!err) {
> > + err = verify_pkcs7_signature(mod, info->len, sig, sig_len,
> > + VERIFY_USE_SECONDARY_KEYRING,
> > + VERIFYING_MODULE_SIGNATURE,
> > + NULL, NULL);
> > if (!err) {
> > info->sig_ok = true;
> > return 0;
>
> The patch looks to modify the behavior when mangled_module is true.
>
> Previously, module_sig_check() didn't attempt to extract the signature
> in such a case and treated the module as unsigned. The err remained set
> to -ENODATA and the function subsequently consulted module_sig_check()
> and security_locked_down() to determine an appropriate result.
>
> Newly, module_sig_check() calls mod_split_sig(), which skips the
> extraction of the marker ("~Module signature appended~\n") from the end
> of the module and instead attempts to read it as an actual
> module_signature. The value is then passed to mod_check_sig() which
> should return -EBADMSG. The error is propagated to module_sig_check()
> and treated as fatal, without consulting module_sig_check() and
> security_locked_down().
>
> I think the mangled_module flag should not be passed to mod_split_sig()
> and it should be handled solely by module_sig_check().
Ack.
(...)
> > diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c
> > index 3265d744d5ce..a57342d39b07 100644
> > --- a/security/integrity/ima/ima_modsig.c
> > +++ b/security/integrity/ima/ima_modsig.c
> > @@ -40,44 +40,30 @@ struct modsig {
> > int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
> > struct modsig **modsig)
> > {
> > - const size_t marker_len = strlen(MODULE_SIG_STRING);
> > - const struct module_signature *sig;
> > + size_t buf_len_sz = buf_len;
> > struct modsig *hdr;
> > size_t sig_len;
> > - const void *p;
> > + const u8 *sig;
> > int rc;
> >
> > - if (buf_len <= marker_len + sizeof(*sig))
> > - return -ENOENT;
> > -
> > - p = buf + buf_len - marker_len;
> > - if (memcmp(p, MODULE_SIG_STRING, marker_len))
> > - return -ENOENT;
> > -
> > - buf_len -= marker_len;
> > - sig = (const struct module_signature *)(p - sizeof(*sig));
> > -
> > - rc = mod_check_sig(sig, buf_len, func_tokens[func]);
> > + rc = mod_split_sig(buf, &buf_len_sz, true, &sig_len, &sig, func_tokens[func]);
>
> Passing mangled=true to mod_split_sig() seems incorrect here. It causes
> that the function doesn't properly extract the signature marker at the
> end of the module, no?
Indeed, thanks.
I am thinking about dropping this patch from the series for now.
It was meant for IMA modsig compatibility, which is not part of the
series anymore.
> > if (rc)
> > return rc;
> >
> > - sig_len = be32_to_cpu(sig->sig_len);
> > - buf_len -= sig_len + sizeof(*sig);
> > -
> > /* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */
> > hdr = kzalloc(struct_size(hdr, raw_pkcs7, sig_len), GFP_KERNEL);
> > if (!hdr)
> > return -ENOMEM;
> >
> > hdr->raw_pkcs7_len = sig_len;
> > - hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len);
> > + hdr->pkcs7_msg = pkcs7_parse_message(sig, sig_len);
> > if (IS_ERR(hdr->pkcs7_msg)) {
> > rc = PTR_ERR(hdr->pkcs7_msg);
> > kfree(hdr);
> > return rc;
> > }
> >
> > - memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len);
> > + memcpy(hdr->raw_pkcs7, sig, sig_len);
> >
> > /* We don't know the hash algorithm yet. */
> > hdr->hash_algo = HASH_ALGO__LAST;
> >
^ permalink raw reply
* Re: [PATCH v4 12/17] module: Move signature splitting up
From: Thomas Weißschuh @ 2026-02-03 12:42 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Sami Tolvanen,
Daniel Gomez, Paul Moore, James Morris, Serge E. Hallyn,
Jonathan Corbet, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Nicolas Schier, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Schier,
Nicolas Bouchinet, Xiu Jianfeng, Fabian Grünbichler,
Arnout Engelen, Mattia Rizzolo, kpcyrd, Christian Heusel,
Câju Mihai-Drosi, Sebastian Andrzej Siewior, linux-kbuild,
linux-kernel, linux-arch, linux-modules, linux-security-module,
linux-doc, linuxppc-dev, linux-integrity
In-Reply-To: <aa92ce4a-d336-4d03-b87d-1c39b1c553da@suse.com>
On 2026-01-29 15:41:43+0100, Petr Pavlu wrote:
> On 1/13/26 1:28 PM, Thomas Weißschuh wrote:
> > The signature splitting will also be used by CONFIG_MODULE_HASHES.
> >
> > Move it up the callchain, so the result can be reused.
> >
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > ---
> > [...]
> > diff --git a/kernel/module/main.c b/kernel/module/main.c
> > index c09b25c0166a..d65bc300a78c 100644
> > --- a/kernel/module/main.c
> > +++ b/kernel/module/main.c
> > @@ -3346,10 +3346,21 @@ static int early_mod_check(struct load_info *info, int flags)
> >
> > static int module_integrity_check(struct load_info *info, int flags)
> > {
> > + bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
> > + MODULE_INIT_IGNORE_VERMAGIC);
> > + size_t sig_len;
> > + const u8 *sig;
> > int err = 0;
> >
> > + if (IS_ENABLED(CONFIG_MODULE_SIG_POLICY)) {
> > + err = mod_split_sig(info->hdr, &info->len, mangled_module,
> > + &sig_len, &sig, "module");
> > + if (err)
> > + return err;
> > + }
> > +
> > if (IS_ENABLED(CONFIG_MODULE_SIG))
> > - err = module_sig_check(info, flags);
> > + err = module_sig_check(info, sig, sig_len);
> >
> > if (err)
> > return err;
>
> I suggest moving the IS_ENABLED(CONFIG_MODULE_SIG) block under the
> new IS_ENABLED(CONFIG_MODULE_SIG_POLICY) section. I realize that
> CONFIG_MODULE_SIG implies CONFIG_MODULE_SIG_POLICY, but I believe this
> change makes it more apparent that this it the case. Otherwise, one
> might for example wonder if sig_len in the module_sig_check() call can
> be undefined.
>
> if (IS_ENABLED(CONFIG_MODULE_SIG_POLICY)) {
> err = mod_split_sig(info->hdr, &info->len, mangled_module,
> &sig_len, &sig, "module");
> if (err)
> return err;
>
> if (IS_ENABLED(CONFIG_MODULE_SIG))
> err = module_sig_check(info, sig, sig_len);
> }
Ack.
^ permalink raw reply
* Re: [PATCH v4 13/17] module: Report signature type to users
From: Thomas Weißschuh @ 2026-02-03 12:44 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Sami Tolvanen,
Daniel Gomez, Paul Moore, James Morris, Serge E. Hallyn,
Jonathan Corbet, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Nicolas Schier, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Schier,
Nicolas Bouchinet, Xiu Jianfeng, Fabian Grünbichler,
Arnout Engelen, Mattia Rizzolo, kpcyrd, Christian Heusel,
Câju Mihai-Drosi, Sebastian Andrzej Siewior, linux-kbuild,
linux-kernel, linux-arch, linux-modules, linux-security-module,
linux-doc, linuxppc-dev, linux-integrity
In-Reply-To: <fd19f9d3-b01c-4cc8-9fd5-642350e7b36b@suse.com>
On 2026-01-29 15:44:31+0100, Petr Pavlu wrote:
> On 1/13/26 1:28 PM, Thomas Weißschuh wrote:
> > The upcoming CONFIG_MODULE_HASHES will introduce a signature type.
> > This needs to be handled by callers differently than PKCS7 signatures.
> >
> > Report the signature type to the caller and let them verify it.
> >
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > ---
> > [...]
> > diff --git a/kernel/module/main.c b/kernel/module/main.c
> > index d65bc300a78c..2a28a0ece809 100644
> > --- a/kernel/module/main.c
> > +++ b/kernel/module/main.c
> > @@ -3348,19 +3348,24 @@ static int module_integrity_check(struct load_info *info, int flags)
> > {
> > bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
> > MODULE_INIT_IGNORE_VERMAGIC);
> > + enum pkey_id_type sig_type;
> > size_t sig_len;
> > const u8 *sig;
> > int err = 0;
> >
> > if (IS_ENABLED(CONFIG_MODULE_SIG_POLICY)) {
> > err = mod_split_sig(info->hdr, &info->len, mangled_module,
> > - &sig_len, &sig, "module");
> > + &sig_type, &sig_len, &sig, "module");
> > if (err)
> > return err;
> > }
> >
> > - if (IS_ENABLED(CONFIG_MODULE_SIG))
> > + if (IS_ENABLED(CONFIG_MODULE_SIG) && sig_type == PKEY_ID_PKCS7) {
> > err = module_sig_check(info, sig, sig_len);
> > + } else {
> > + pr_err("module: not signed with expected PKCS#7 message\n");
> > + err = -ENOPKG;
> > + }
>
> The new else branch means that if the user chooses not to configure any
> module integrity policy, they will no longer be able to load any
> modules. I think this entire if-else part should be moved under the
> IS_ENABLED(CONFIG_MODULE_SIG_POLICY) block above, as I'm mentioning on
> patch #12.
Ack.
^ permalink raw reply
* Re: [PATCH v4 15/17] module: Introduce hash-based integrity checking
From: Thomas Weißschuh @ 2026-02-03 12:55 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Sami Tolvanen,
Daniel Gomez, Paul Moore, James Morris, Serge E. Hallyn,
Jonathan Corbet, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Nicolas Schier, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Schier,
Nicolas Bouchinet, Xiu Jianfeng, Fabian Grünbichler,
Arnout Engelen, Mattia Rizzolo, kpcyrd, Christian Heusel,
Câju Mihai-Drosi, Sebastian Andrzej Siewior, linux-kbuild,
linux-kernel, linux-arch, linux-modules, linux-security-module,
linux-doc, linuxppc-dev, linux-integrity
In-Reply-To: <db1ed045-d7b6-49dc-b111-9fea7c30f8ab@suse.com>
On 2026-01-30 18:06:20+0100, Petr Pavlu wrote:
> On 1/13/26 1:28 PM, Thomas Weißschuh wrote:
> > Normally the .ko module files depend on a fully built vmlinux to be
> > available for modpost validation and BTF generation. With
> > CONFIG_MODULE_HASHES, vmlinux now depends on the modules
> > to build a merkle tree. This introduces a dependency cycle which is
> > impossible to satisfy. Work around this by building the modules during
> > link-vmlinux.sh, after vmlinux is complete enough for modpost and BTF
> > but before the final module hashes are
>
> I wonder if this dependency cycle could be resolved by utilizing the
> split into vmlinux.unstripped and vmlinux that occurred last year.
>
> The idea is to create the following ordering: vmlinux.unstripped ->
> modules -> vmlinux, and to patch in .module_hashes only when building
> the final vmlinux.
>
> This would require the following:
> * Split scripts/Makefile.vmlinux into two Makefiles, one that builds the
> current vmlinux.unstripped and the second one that builds the final
> vmlinux from it.
> * Modify the top Makefile to recognize vmlinux.unstripped and update the
> BTF generation rule 'modules: vmlinux' to
> 'modules: vmlinux.unstripped'.
> * Add the 'vmlinux: modules' ordering in the top Makefile for
> CONFIG_MODULE_HASHES=y.
> * Remove the patching of vmlinux.unstripped in scripts/link-vmlinux.sh
> and instead move it into scripts/Makefile.vmlinux when running objcopy
> to produce the final vmlinux.
>
> I think this approach has two main advantages:
> * CONFIG_MODULE_HASHES can be made orthogonal to
> CONFIG_DEBUG_INFO_BTF_MODULES.
> * All dependencies are expressed at the Makefile level instead of having
> scripts/link-vmlinux.sh invoke 'make -f Makefile modules'.
>
> Below is a rough prototype that applies on top of this series. It is a
> bit verbose due to the splitting of part of scripts/Makefile.vmlinux
> into scripts/Makefile.vmlinux_unstripped.
That looks like a feasible alternative. Before adopting it, I'd like to
hear the preference of the kbuild folks.
> diff --git a/Makefile b/Makefile
> index 841772a5a260..19a3beb82fa7 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1259,7 +1259,7 @@ vmlinux_o: vmlinux.a $(KBUILD_VMLINUX_LIBS)
> vmlinux.o modules.builtin.modinfo modules.builtin: vmlinux_o
> @:
>
> -PHONY += vmlinux
> +PHONY += vmlinux.unstripped vmlinux
> # LDFLAGS_vmlinux in the top Makefile defines linker flags for the top vmlinux,
> # not for decompressors. LDFLAGS_vmlinux in arch/*/boot/compressed/Makefile is
> # unrelated; the decompressors just happen to have the same base name,
> @@ -1270,9 +1270,11 @@ PHONY += vmlinux
> # https://savannah.gnu.org/bugs/?61463
> # For Make > 4.4, the following simple code will work:
> # vmlinux: private export LDFLAGS_vmlinux := $(LDFLAGS_vmlinux)
> -vmlinux: private _LDFLAGS_vmlinux := $(LDFLAGS_vmlinux)
> -vmlinux: export LDFLAGS_vmlinux = $(_LDFLAGS_vmlinux)
> -vmlinux: vmlinux.o $(KBUILD_LDS) modpost
> +vmlinux.unstripped: private _LDFLAGS_vmlinux := $(LDFLAGS_vmlinux)
> +vmlinux.unstripped: export LDFLAGS_vmlinux = $(_LDFLAGS_vmlinux)
> +vmlinux.unstripped: vmlinux.o $(KBUILD_LDS) modpost
> + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux_unstripped
> +vmlinux: vmlinux.unstripped
> $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux
Maybe we could keep them together in a single Makefile,
and instead have different targets in it.
(...)
> @@ -98,70 +44,15 @@ remove-symbols := -w --strip-unneeded-symbol='__mod_device_table__*'
> # To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy,
> # it is necessary to remove the PT_LOAD flag from the segment.
> quiet_cmd_strip_relocs = OBJCOPY $@
> - cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \
> - $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@
> + cmd_script_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \
> + $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) \
> + $(remove-symbols) \
> + $(patch-module-hashes) $@
cmd_script_relocs -> cmd_strip_relocs
(...)
^ permalink raw reply
* Re: [PATCH v4 15/17] module: Introduce hash-based integrity checking
From: Thomas Weißschuh @ 2026-02-03 12:59 UTC (permalink / raw)
To: Petr Pavlu
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Sami Tolvanen,
Daniel Gomez, Paul Moore, James Morris, Serge E. Hallyn,
Jonathan Corbet, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Naveen N Rao, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Nicolas Schier, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Schier,
Nicolas Bouchinet, Xiu Jianfeng, Fabian Grünbichler,
Arnout Engelen, Mattia Rizzolo, kpcyrd, Christian Heusel,
Câju Mihai-Drosi, Sebastian Andrzej Siewior, linux-kbuild,
linux-kernel, linux-arch, linux-modules, linux-security-module,
linux-doc, linuxppc-dev, linux-integrity
In-Reply-To: <fab2af64-e396-45f9-8876-feff4002e04b@suse.com>
On 2026-02-03 13:19:20+0100, Petr Pavlu wrote:
> On 1/13/26 1:28 PM, Thomas Weißschuh wrote:
> > The current signature-based module integrity checking has some drawbacks
> > in combination with reproducible builds. Either the module signing key
> > is generated at build time, which makes the build unreproducible, or a
> > static signing key is used, which precludes rebuilds by third parties
> > and makes the whole build and packaging process much more complicated.
> >
> > The goal is to reach bit-for-bit reproducibility. Excluding certain
> > parts of the build output from the reproducibility analysis would be
> > error-prone and force each downstream consumer to introduce new tooling.
> >
> > Introduce a new mechanism to ensure only well-known modules are loaded
> > by embedding a merkle tree root of all modules built as part of the full
> > kernel build into vmlinux.
> >
> > Non-builtin modules can be validated as before through signatures.
> >
> > Normally the .ko module files depend on a fully built vmlinux to be
> > available for modpost validation and BTF generation. With
> > CONFIG_MODULE_HASHES, vmlinux now depends on the modules
> > to build a merkle tree. This introduces a dependency cycle which is
> > impossible to satisfy. Work around this by building the modules during
> > link-vmlinux.sh, after vmlinux is complete enough for modpost and BTF
> > but before the final module hashes are
> >
> > The PKCS7 format which is used for regular module signatures can not
> > represent Merkle proofs, so a new kind of module signature is
> > introduced. As this signature type is only ever used for builtin
> > modules, no compatibility issues can arise.
>
> Nit: The description uses the term "builtin modules" in a misleading
> way. Typically, "builtin modules" refers to modules that are linked
> directly into vmlinux. However, this text uses the term to refer to
> loadable modules that are built together with the main kernel image,
> which is something different.
Agreed. I'll go through everything again, to consistently use "in-tree".
(...)
> > +
> > + while (fgets(line, PATH_MAX, in)) {
> > + struct file_entry *entry;
> > +
> > + fh_list = xreallocarray(fh_list, num_files + 1, sizeof(*fh_list));
>
> It might be useful to not reallocate this array for each file, although
> I don't immediately see that it contributes any significant time to the
> runtime.
The libc implementation should optimize this internally to not actually
grow one elemet at a time. I'd like to keep this as-is.
(...)
Ack to everything else.
^ permalink raw reply
* Re: IMA and PQC
From: Coiby Xu @ 2026-02-03 13:32 UTC (permalink / raw)
To: Johannes Wiesböck
Cc: dhowells, dmitry.kasatkin, ebiggers, eric.snowberg, keyrings,
linux-crypto, linux-integrity, linux-kernel, linux-modules,
roberto.sassu, simo, zohar, michael.weiss
In-Reply-To: <20260130203126.662082-1-johannes.wiesboeck@aisec.fraunhofer.de>
On Fri, Jan 30, 2026 at 09:31:26PM +0100, Johannes Wiesböck wrote:
>Hi all,
Hi Johannes,
>
>we conducted an evaluation regarding PQC use in IMA last year (see [1] for all
>details) where we also considered the interplay of different PQC signatures and
>file systems (ext4, btrfs, XFS, f2fs).
Thanks for sharing this comprehensive study! There are many nuances in
this research paper!
>
>Coiby Xu <coxu@redhat.com> wrote:
>
>>According to my experiments done so far, for verification speed,
>>ML-DSA-65 is consistently faster than ECDSA P-384 which is used by
>>current CentOS/RHEL to sign files in a package.
>
>Regarding performance, similar to Coiby, we found that all variants of ML-DSA
>consistently outperformed ECDSA P-256.
Glad to know ML-DSA is also faster than ECDSA P-256!
>
>>The size of a single ML-DSA-65 signature indeed increases dramatically
>>compared with ECDSA P-384 (3309 bytes vs ~100 bytes). But I'm not sure
>>it can be a big problem when considering the storage capacity. Take
>>latest fresh CentOS Stream 10 x86_64 KVM guest as example, without any
>>file system optimization, extra ~189MB disk space is needed if all files
>>in /usr signed using by ML-DSA-65 where the disk size is 50G. But I
>>don't have enough experience to tell how users will perceive it and I'll
>>try to collect more feedback.
>>
>>For the details of my experiments, you can check
>>https://gist.github.com/coiby/41cf3a4d59cd64fb19d35b9ac42e4cd7
>>And here's the tldr; version,
>>- Verification Speed: ML-DSA-65 is consistently ~10-12% faster
>> at verification than ECDSA P-384 when verifying all files in /usr;
>> ML-DSA-65 is 2.5x or 3x faster by "openssl speed"
>>
>>- Signing Speed: ML-DSA-65 appears ~25-30% slower when signing
>> all files in /usr; ML-DSA-65 is 4x or 4.8x slower by "openssl speed"
>>
>>- Storage overhead: For ML-DSA-65, /usr will increase by 189MB and
>> 430MB when there are 27346 and 58341 files respectively. But total
>> size of pure IMA signatures are estimated (files x (3309+20) bytes) to
>> be ~87MB and ~185MB respectively.
>
>Two relevant aspects we discovered regard the signature size. TL;DR:
>
>1. Most file systems need to be tuned to support the larger extended attributes
>(signatures) if their size goes above a certain threshold (e.g. enable EA_INODE
>in ext4). This influences not only disk usage but overall compatibility between
>file systems and PQC signatures. A file system that would not provide the
>functionality to store larger extended attributes would be incompatible with
>large signatures.
>
>2. For most smaller signatures (like ML-DSA-44/65), we believe that the overhead
>of signatures is actually compensated by fragmentation within the file systems.
>For example, ext4 will allocate a full file system block for extended attributes.
>As long as the signature size is below this block size, we did not observe less
>free space on the file system despite the larger signatures.
I think this explains why I didn't see any disk overhead when using ECDSA P-384:)
>
>Overall, we concluded that ML-DSA-65 provides the best combination of disk
>overhead, performance and security level. Performace was good and for all
>algorithms with larger signatures than ML-DSA-65, file systems would need to be
>tuned.
Thanks for summarizing your findings regarding the signature size and
also sharing your evaluation!
>
>>According to
>>https://www.ietf.org/archive/id/draft-salter-lamps-cms-ml-dsa-00.html
>>ML-DSA-44 is intended to meet NIST's level 2 security category. Will
>>NIST level 2 meet users' security requirements?
>
>Regarding security levels:
>For security levels, we referred to NIST IR 8547 ipd [2].
>ECDSA P-256 has a classical security strength of 128bits (P-384: 192bits).
>According to [2] Table 3, these levels are met by the different ML-DSA variants.
>So, if you are migrating from ECDSA P-384, you need to use at least ML-DSA-65 to
>meet the same security strength.
This is helpful info! And thanks for sharing the perspective of
migration!
>
>Best regards,
>Johannes
>
>[1] https://www.wsbck.net/publications/pqc-ima.pdf
>[2] https://nvlpubs.nist.gov/nistpubs/ir/2024/NIST.IR.8547.ipd.pdf
>
--
Best regards,
Coiby
^ permalink raw reply
* Re: IMA and PQC
From: Coiby Xu @ 2026-02-03 13:43 UTC (permalink / raw)
To: David Howells
Cc: Mimi Zohar, Simo Sorce, Roberto Sassu, Dmitry Kasatkin,
Eric Snowberg, Eric Biggers, linux-integrity, linux-crypto,
keyrings, linux-modules, linux-kernel
In-Reply-To: <2265997.1769782221@warthog.procyon.org.uk>
On Fri, Jan 30, 2026 at 02:10:21PM +0000, David Howells wrote:
>Coiby Xu <coxu@redhat.com> wrote:
>
>> Take latest fresh CentOS Stream 10 x86_64 KVM guest as example, without any
>> file system optimization, extra ~189MB disk space is needed if all files in
>> /usr signed using by ML-DSA-65 where the disk size is 50G.
>
>Is that storing raw signatures rather than PKCS#7 wrapped signatures?
Yes, it's storing raw signatures + per ~20 bytes overhead including the
4-byte key ID.
>
>David
>
--
Best regards,
Coiby
^ permalink raw reply
* [PATCH] module: Fix the modversions and signing submenus
From: Petr Pavlu @ 2026-02-05 14:37 UTC (permalink / raw)
To: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen
Cc: Aaron Tomlin, linux-modules, linux-kernel
The module Kconfig file contains a set of options related to "Module
versioning support" (depends on MODVERSIONS) and "Module signature
verification" (depends on MODULE_SIG). The Kconfig tool automatically
creates submenus when an entry for a symbol is followed by consecutive
items that all depend on the symbol. However, this functionality doesn't
work for the mentioned module options. The MODVERSIONS options are
interleaved with ASM_MODVERSIONS, which has no 'depends on MODVERSIONS' but
instead uses 'default HAVE_ASM_MODVERSIONS && MODVERSIONS'. Similarly, the
MODULE_SIG options are interleaved by a comment warning not to forget
signing modules with scripts/sign-file, which uses the condition 'depends
on MODULE_SIG_FORCE && !MODULE_SIG_ALL'.
The result is that the options are confusingly shown when using
a menuconfig tool, as follows:
[*] Module versioning support
Module versioning implementation (genksyms (from source code)) --->
[ ] Extended Module Versioning Support
[*] Basic Module Versioning Support
[*] Source checksum for all modules
[*] Module signature verification
[ ] Require modules to be validly signed
[ ] Automatically sign all modules
Hash algorithm to sign modules (SHA-256) --->
Fix the issue by using if/endif to group related options together in
kernel/module/Kconfig, similarly to how the MODULE_DEBUG options are
already grouped. Note that the signing-related options depend on
'MODULE_SIG || IMA_APPRAISE_MODSIG', with the exception of
MODULE_SIG_FORCE, which is valid only for MODULE_SIG and is therefore kept
separately. For consistency, do the same for the MODULE_COMPRESS entries.
The options are then properly placed into submenus, as follows:
[*] Module versioning support
Module versioning implementation (genksyms (from source code)) --->
[ ] Extended Module Versioning Support
[*] Basic Module Versioning Support
[*] Source checksum for all modules
[*] Module signature verification
[ ] Require modules to be validly signed
[ ] Automatically sign all modules
Hash algorithm to sign modules (SHA-256) --->
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/module/Kconfig | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
index 2a1beebf1d37..537985387ff3 100644
--- a/kernel/module/Kconfig
+++ b/kernel/module/Kconfig
@@ -169,9 +169,10 @@ config MODVERSIONS
make them incompatible with the kernel you are running. If
unsure, say N.
+if MODVERSIONS
+
choice
prompt "Module versioning implementation"
- depends on MODVERSIONS
help
Select the tool used to calculate symbol versions for modules.
@@ -206,7 +207,7 @@ endchoice
config ASM_MODVERSIONS
bool
- default HAVE_ASM_MODVERSIONS && MODVERSIONS
+ default HAVE_ASM_MODVERSIONS
help
This enables module versioning for exported symbols also from
assembly. This can be enabled only when the target architecture
@@ -214,7 +215,6 @@ config ASM_MODVERSIONS
config EXTENDED_MODVERSIONS
bool "Extended Module Versioning Support"
- depends on MODVERSIONS
help
This enables extended MODVERSIONs support, allowing long symbol
names to be versioned.
@@ -224,7 +224,6 @@ config EXTENDED_MODVERSIONS
config BASIC_MODVERSIONS
bool "Basic Module Versioning Support"
- depends on MODVERSIONS
default y
help
This enables basic MODVERSIONS support, allowing older tools or
@@ -237,6 +236,8 @@ config BASIC_MODVERSIONS
This is enabled by default when MODVERSIONS are enabled.
If unsure, say Y.
+endif # MODVERSIONS
+
config MODULE_SRCVERSION_ALL
bool "Source checksum for all modules"
help
@@ -277,10 +278,11 @@ config MODULE_SIG_FORCE
Reject unsigned modules or signed modules for which we don't have a
key. Without this, such modules will simply taint the kernel.
+if MODULE_SIG || IMA_APPRAISE_MODSIG
+
config MODULE_SIG_ALL
bool "Automatically sign all modules"
default y
- depends on MODULE_SIG || IMA_APPRAISE_MODSIG
help
Sign all modules during make modules_install. Without this option,
modules must be signed manually, using the scripts/sign-file tool.
@@ -290,7 +292,6 @@ comment "Do not forget to sign required modules with scripts/sign-file"
choice
prompt "Hash algorithm to sign modules"
- depends on MODULE_SIG || IMA_APPRAISE_MODSIG
default MODULE_SIG_SHA512
help
This determines which sort of hashing algorithm will be used during
@@ -331,7 +332,6 @@ endchoice
config MODULE_SIG_HASH
string
- depends on MODULE_SIG || IMA_APPRAISE_MODSIG
default "sha1" if MODULE_SIG_SHA1
default "sha256" if MODULE_SIG_SHA256
default "sha384" if MODULE_SIG_SHA384
@@ -340,6 +340,8 @@ config MODULE_SIG_HASH
default "sha3-384" if MODULE_SIG_SHA3_384
default "sha3-512" if MODULE_SIG_SHA3_512
+endif # MODULE_SIG || IMA_APPRAISE_MODSIG
+
config MODULE_COMPRESS
bool "Module compression"
help
@@ -355,9 +357,10 @@ config MODULE_COMPRESS
If unsure, say N.
+if MODULE_COMPRESS
+
choice
prompt "Module compression type"
- depends on MODULE_COMPRESS
help
Choose the supported algorithm for module compression.
@@ -384,7 +387,6 @@ endchoice
config MODULE_COMPRESS_ALL
bool "Automatically compress all modules"
default y
- depends on MODULE_COMPRESS
help
Compress all modules during 'make modules_install'.
@@ -394,7 +396,6 @@ config MODULE_COMPRESS_ALL
config MODULE_DECOMPRESS
bool "Support in-kernel module decompression"
- depends on MODULE_COMPRESS
select ZLIB_INFLATE if MODULE_COMPRESS_GZIP
select XZ_DEC if MODULE_COMPRESS_XZ
select ZSTD_DECOMPRESS if MODULE_COMPRESS_ZSTD
@@ -405,6 +406,8 @@ config MODULE_DECOMPRESS
If unsure, say N.
+endif # MODULE_COMPRESS
+
config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
bool "Allow loading of modules with missing namespace imports"
help
base-commit: 6bd9ed02871f22beb0e50690b0c3caf457104f7c
--
2.52.0
^ permalink raw reply related
* [PATCH v16 8/7] pkcs7: Change a pr_warn() to pr_warn_once()
From: David Howells @ 2026-02-05 15:47 UTC (permalink / raw)
To: Lukas Wunner, Ignat Korchagin
Cc: dhowells, Jarkko Sakkinen, Herbert Xu, Eric Biggers,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Jason A . Donenfeld, Ard Biesheuvel, Stephan Mueller,
linux-crypto, keyrings, linux-modules, linux-kernel
In-Reply-To: <20260202170216.2467036-1-dhowells@redhat.com>
Only display the "PKCS7: Waived invalid module sig (has authattrs)" once.
Suggested-by: Lenny Szubowicz <lszubowi@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Lenny Szubowicz <lszubowi@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Jarkko Sakkinen <jarkko@kernel.org>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
---
crypto/asymmetric_keys/pkcs7_verify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 519eecfe6778..474e2c1ae21b 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -427,7 +427,7 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
if (pkcs7->have_authattrs) {
#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
if (pkcs7->authattrs_rej_waivable) {
- pr_warn("Waived invalid module sig (has authattrs)\n");
+ pr_warn_once("Waived invalid module sig (has authattrs)\n");
break;
}
#endif
^ permalink raw reply related
* Re: [PATCH v4 05/17] module: Switch load_info::len to size_t
From: David Howells @ 2026-02-06 8:18 UTC (permalink / raw)
To: =?utf-8?q?Thomas_Wei=C3=9Fschuh?=
Cc: dhowells, Nathan Chancellor, Arnd Bergmann, Luis Chamberlain,
Petr Pavlu, Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Nicolas Schier,
Daniel Gomez, Aaron Tomlin, Christophe Leroy (CS GROUP),
Nicolas Schier, Nicolas Bouchinet, Xiu Jianfeng,
Fabian Grünbichler, Arnout Engelen, Mattia Rizzolo, kpcyrd,
Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-5-0b932db9b56b@weissschuh.net>
Thomas Weißschuh <linux@weissschuh.net> wrote:
> As both 'size_t' and 'unsigned int' are always the same size, this
> should be risk-free.
Did you mean 'unsigned long'?
David
^ permalink raw reply
* Re: [PATCH v4 02/17] powerpc/ima: Drop unnecessary check for CONFIG_MODULE_SIG
From: Nicolas Schier @ 2026-02-06 8:25 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Petr Pavlu,
Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Bouchinet,
Xiu Jianfeng, Fabian Grünbichler, Arnout Engelen,
Mattia Rizzolo, kpcyrd, Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-2-0b932db9b56b@weissschuh.net>
On Tue, Jan 13, 2026 at 01:28:46PM +0100, Thomas Weißschuh wrote:
> When CONFIG_MODULE_SIG is disabled set_module_sig_enforced() is defined
> as an empty stub, so the check is unnecessary.
> The specific configuration option for set_module_sig_enforced() is
> about to change and removing the check avoids some later churn.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> arch/powerpc/kernel/ima_arch.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
--
Nicolas
^ permalink raw reply
* Re: [PATCH v4 03/17] ima: efi: Drop unnecessary check for CONFIG_MODULE_SIG/CONFIG_KEXEC_SIG
From: Nicolas Schier @ 2026-02-06 8:25 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Petr Pavlu,
Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Bouchinet,
Xiu Jianfeng, Fabian Grünbichler, Arnout Engelen,
Mattia Rizzolo, kpcyrd, Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-3-0b932db9b56b@weissschuh.net>
On Tue, Jan 13, 2026 at 01:28:47PM +0100, Thomas Weißschuh wrote:
> When configuration settings are disabled the guarded functions are
> defined as empty stubs, so the check is unnecessary.
> The specific configuration option for set_module_sig_enforced() is
> about to change and removing the checks avoids some later churn.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> security/integrity/ima/ima_efi.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
--
Nicolas
^ permalink raw reply
* Re: [PATCH v4 04/17] module: Make mod_verify_sig() static
From: Nicolas Schier @ 2026-02-06 8:25 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Petr Pavlu,
Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Bouchinet,
Xiu Jianfeng, Fabian Grünbichler, Arnout Engelen,
Mattia Rizzolo, kpcyrd, Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-4-0b932db9b56b@weissschuh.net>
On Tue, Jan 13, 2026 at 01:28:48PM +0100, Thomas Weißschuh wrote:
> It is not used outside of signing.c.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> kernel/module/internal.h | 1 -
> kernel/module/signing.c | 2 +-
> 2 files changed, 1 insertion(+), 2 deletions(-)
>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
--
Nicolas
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox