* [PATCH v11 7/8] pkcs7, x509: Add RSASSA-PSS support
From: David Howells @ 2026-01-05 15:21 UTC (permalink / raw)
To: Lukas Wunner, Ignat Korchagin
Cc: David Howells, 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: <20260105152145.1801972-1-dhowells@redhat.com>
Add support for RSASSA-PSS keys and signatures to the PKCS#7 and X.509
implementations. This requires adding support for algorithm parameters for
keys and signatures as RSASSA-PSS needs metadata. The ASN.1 encoded data
is converted into a printable key=value list string and passed to the
verification code.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
---
crypto/asymmetric_keys/Makefile | 12 +-
crypto/asymmetric_keys/mgf1_params.asn1 | 12 ++
crypto/asymmetric_keys/pkcs7.asn1 | 2 +-
crypto/asymmetric_keys/pkcs7_parser.c | 113 ++++++-----
crypto/asymmetric_keys/public_key.c | 10 +
crypto/asymmetric_keys/rsassa_params.asn1 | 25 +++
crypto/asymmetric_keys/rsassa_parser.c | 233 ++++++++++++++++++++++
crypto/asymmetric_keys/rsassa_parser.h | 25 +++
crypto/asymmetric_keys/x509.asn1 | 2 +-
crypto/asymmetric_keys/x509_cert_parser.c | 96 +++++----
crypto/asymmetric_keys/x509_parser.h | 33 ++-
crypto/asymmetric_keys/x509_public_key.c | 28 ++-
include/linux/oid_registry.h | 2 +
13 files changed, 490 insertions(+), 103 deletions(-)
create mode 100644 crypto/asymmetric_keys/mgf1_params.asn1
create mode 100644 crypto/asymmetric_keys/rsassa_params.asn1
create mode 100644 crypto/asymmetric_keys/rsassa_parser.c
create mode 100644 crypto/asymmetric_keys/rsassa_parser.h
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index bc65d3b98dcb..c5aed382ee8a 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -21,7 +21,11 @@ x509_key_parser-y := \
x509_akid.asn1.o \
x509_cert_parser.o \
x509_loader.o \
- x509_public_key.o
+ x509_public_key.o \
+ rsassa_params.asn1.o \
+ rsassa_parser.o \
+ mgf1_params.asn1.o
+
obj-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += x509_selftest.o
x509_selftest-y += selftest.o
x509_selftest-$(CONFIG_FIPS_SIGNATURE_SELFTEST_RSA) += selftest_rsa.o
@@ -31,8 +35,14 @@ $(obj)/x509_cert_parser.o: \
$(obj)/x509.asn1.h \
$(obj)/x509_akid.asn1.h
+$(obj)/rsassa_parser.o: \
+ $(obj)/rsassa_params.asn1.h \
+ $(obj)/mgf1_params.asn1.h
+
$(obj)/x509.asn1.o: $(obj)/x509.asn1.c $(obj)/x509.asn1.h
$(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h
+$(obj)/rsassa_params.asn1.o: $(obj)/rsassa_params.asn1.c $(obj)/rsassa_params.asn1.h
+$(obj)/mgf1_params.asn1.o: $(obj)/mgf1_params.asn1.c $(obj)/mgf1_params.asn1.h
#
# PKCS#8 private key handling
diff --git a/crypto/asymmetric_keys/mgf1_params.asn1 b/crypto/asymmetric_keys/mgf1_params.asn1
new file mode 100644
index 000000000000..c3bc4643e72c
--- /dev/null
+++ b/crypto/asymmetric_keys/mgf1_params.asn1
@@ -0,0 +1,12 @@
+-- SPDX-License-Identifier: BSD-3-Clause
+--
+-- Copyright (C) 2009 IETF Trust and the persons identified as authors
+-- of the code
+--
+--
+-- https://datatracker.ietf.org/doc/html/rfc4055 Section 6.
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ mgf1_note_OID }),
+ parameters ANY OPTIONAL
+}
diff --git a/crypto/asymmetric_keys/pkcs7.asn1 b/crypto/asymmetric_keys/pkcs7.asn1
index 28e1f4a41c14..03c2248f23bc 100644
--- a/crypto/asymmetric_keys/pkcs7.asn1
+++ b/crypto/asymmetric_keys/pkcs7.asn1
@@ -124,7 +124,7 @@ UnauthenticatedAttribute ::= SEQUENCE {
DigestEncryptionAlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER ({ pkcs7_note_OID }),
- parameters ANY OPTIONAL
+ parameters ANY OPTIONAL ({ pkcs7_sig_note_algo_params })
}
EncryptedDigest ::= OCTET STRING ({ pkcs7_sig_note_signature })
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 90c36fe1b5ed..81996b60c1f1 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -14,6 +14,7 @@
#include <linux/oid_registry.h>
#include <crypto/public_key.h>
#include "pkcs7_parser.h"
+#include "rsassa_parser.h"
#include "pkcs7.asn1.h"
MODULE_DESCRIPTION("PKCS#7 parser");
@@ -30,6 +31,8 @@ struct pkcs7_parse_context {
enum OID last_oid; /* Last OID encountered */
unsigned x509_index;
unsigned sinfo_index;
+ unsigned algo_params_size;
+ const void *algo_params;
const void *raw_serial;
unsigned raw_serial_size;
unsigned raw_issuer_size;
@@ -225,45 +228,29 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
const void *value, size_t vlen)
{
struct pkcs7_parse_context *ctx = context;
+ const char *algo;
- switch (ctx->last_oid) {
- case OID_sha1:
- ctx->sinfo->sig->hash_algo = "sha1";
- break;
- case OID_sha256:
- ctx->sinfo->sig->hash_algo = "sha256";
- break;
- case OID_sha384:
- ctx->sinfo->sig->hash_algo = "sha384";
- break;
- case OID_sha512:
- ctx->sinfo->sig->hash_algo = "sha512";
- break;
- case OID_sha224:
- ctx->sinfo->sig->hash_algo = "sha224";
- break;
- case OID_sm3:
- ctx->sinfo->sig->hash_algo = "sm3";
- break;
- case OID_gost2012Digest256:
- ctx->sinfo->sig->hash_algo = "streebog256";
- break;
- case OID_gost2012Digest512:
- ctx->sinfo->sig->hash_algo = "streebog512";
- break;
- case OID_sha3_256:
- ctx->sinfo->sig->hash_algo = "sha3-256";
- break;
- case OID_sha3_384:
- ctx->sinfo->sig->hash_algo = "sha3-384";
- break;
- case OID_sha3_512:
- ctx->sinfo->sig->hash_algo = "sha3-512";
- break;
- default:
- printk("Unsupported digest algo: %u\n", ctx->last_oid);
+ algo = oid_to_hash(ctx->last_oid);
+ if (!algo) {
+ pr_notice("Unsupported digest algo: %u\n", ctx->last_oid);
return -ENOPKG;
}
+
+ ctx->sinfo->sig->hash_algo = algo;
+ return 0;
+}
+
+/*
+ * Note the parameters for the signature.
+ */
+int pkcs7_sig_note_algo_params(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct pkcs7_parse_context *ctx = context;
+
+ ctx->algo_params = value - hdrlen;
+ ctx->algo_params_size = vlen + hdrlen;
return 0;
}
@@ -275,12 +262,16 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
const void *value, size_t vlen)
{
struct pkcs7_parse_context *ctx = context;
+ struct public_key_signature *sig = ctx->sinfo->sig;
+ int err;
switch (ctx->last_oid) {
case OID_rsaEncryption:
- ctx->sinfo->sig->pkey_algo = "rsa";
- ctx->sinfo->sig->encoding = "pkcs1";
+ sig->pkey_algo = "rsa";
+ sig->encoding = "pkcs1";
break;
+ case OID_id_rsassa_pss:
+ goto rsassa_pss;
case OID_id_ecdsa_with_sha1:
case OID_id_ecdsa_with_sha224:
case OID_id_ecdsa_with_sha256:
@@ -289,34 +280,52 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
case OID_id_ecdsa_with_sha3_256:
case OID_id_ecdsa_with_sha3_384:
case OID_id_ecdsa_with_sha3_512:
- ctx->sinfo->sig->pkey_algo = "ecdsa";
- ctx->sinfo->sig->encoding = "x962";
+ sig->pkey_algo = "ecdsa";
+ sig->encoding = "x962";
break;
case OID_gost2012PKey256:
case OID_gost2012PKey512:
- ctx->sinfo->sig->pkey_algo = "ecrdsa";
- ctx->sinfo->sig->encoding = "raw";
+ sig->pkey_algo = "ecrdsa";
+ 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_does_hash = true;
+ sig->pkey_algo = "mldsa44";
+ sig->encoding = "raw";
+ sig->algo_does_hash = true;
break;
case OID_id_ml_dsa_65:
- ctx->sinfo->sig->pkey_algo = "mldsa65";
- ctx->sinfo->sig->encoding = "raw";
- ctx->sinfo->sig->algo_does_hash = true;
+ sig->pkey_algo = "mldsa65";
+ sig->encoding = "raw";
+ sig->algo_does_hash = true;
break;
case OID_id_ml_dsa_87:
- ctx->sinfo->sig->pkey_algo = "mldsa87";
- ctx->sinfo->sig->encoding = "raw";
- ctx->sinfo->sig->algo_does_hash = true;
+ sig->pkey_algo = "mldsa87";
+ sig->encoding = "raw";
+ sig->algo_does_hash = true;
break;
default:
- printk("Unsupported pkey algo: %u\n", ctx->last_oid);
+ pr_notice("Unsupported pkey algo: %u\n", ctx->last_oid);
return -ENOPKG;
}
+
+out:
+ ctx->algo_params = NULL;
+ ctx->algo_params_size = 0;
return 0;
+
+rsassa_pss:
+ if (!ctx->algo_params || !ctx->algo_params_size) {
+ pr_debug("RSASSA-PSS sig algo without parameters\n");
+ return -EBADMSG;
+ }
+
+ err = rsassa_parse_sig_params(sig, ctx->algo_params, ctx->algo_params_size);
+ if (err < 0)
+ return err;
+
+ sig->pkey_algo = "rsa";
+ sig->encoding = "emsa-pss";
+ goto out;
}
/*
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 61dc4f626620..13a5616becaa 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -100,6 +100,16 @@ software_key_determine_akcipher(const struct public_key *pkey,
}
return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
}
+ if (strcmp(encoding, "emsa-pss") == 0) {
+ if (op != kernel_pkey_sign &&
+ op != kernel_pkey_verify)
+ return -EINVAL;
+ *sig = true;
+ if (!hash_algo)
+ hash_algo = "none";
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "rsassa-pss");
+ return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+ }
if (strcmp(encoding, "raw") != 0)
return -EINVAL;
/*
diff --git a/crypto/asymmetric_keys/rsassa_params.asn1 b/crypto/asymmetric_keys/rsassa_params.asn1
new file mode 100644
index 000000000000..95a4e5f0dcd5
--- /dev/null
+++ b/crypto/asymmetric_keys/rsassa_params.asn1
@@ -0,0 +1,25 @@
+-- SPDX-License-Identifier: BSD-3-Clause
+--
+-- Copyright (C) 2009 IETF Trust and the persons identified as authors
+-- of the code
+--
+--
+-- https://datatracker.ietf.org/doc/html/rfc4055 Section 6.
+
+RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm,
+ maskGenAlgorithm [1] MaskGenAlgorithm,
+ saltLength [2] INTEGER ({ rsassa_note_salt_length }),
+ trailerField [3] TrailerField OPTIONAL
+}
+
+TrailerField ::= INTEGER ({ rsassa_note_trailer })
+-- { trailerFieldBC(1) }
+
+HashAlgorithm ::= AlgorithmIdentifier ({ rsassa_note_hash_algo })
+MaskGenAlgorithm ::= AlgorithmIdentifier ({ rsassa_note_maskgen_algo })
+
+AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER ({ rsassa_note_OID }),
+ parameters ANY OPTIONAL ({ rsassa_note_params })
+}
diff --git a/crypto/asymmetric_keys/rsassa_parser.c b/crypto/asymmetric_keys/rsassa_parser.c
new file mode 100644
index 000000000000..8c598517f785
--- /dev/null
+++ b/crypto/asymmetric_keys/rsassa_parser.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* RSASSA-PSS ASN.1 parameter parser
+ *
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#define pr_fmt(fmt) "RSAPSS: "fmt
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/asn1.h>
+#include <crypto/hash.h>
+#include <crypto/hash_info.h>
+#include <crypto/public_key.h>
+#include "x509_parser.h"
+#include "rsassa_parser.h"
+#include "rsassa_params.asn1.h"
+#include "mgf1_params.asn1.h"
+
+struct rsassa_parse_context {
+ struct rsassa_parameters *rsassa; /* The parsed parameters */
+ unsigned long data; /* Start of data */
+ const void *params; /* Algo parameters */
+ unsigned int params_len; /* Length of algo parameters */
+ enum OID last_oid; /* Last OID encountered */
+ enum OID mgf1_last_oid; /* Last OID encountered in MGF1 */
+};
+
+/*
+ * Parse an RSASSA parameter block.
+ */
+struct rsassa_parameters *rsassa_params_parse(const void *data, size_t datalen)
+{
+ struct rsassa_parse_context ctx = {};
+ struct rsassa_parameters *rsassa __free(kfree);
+ long ret;
+
+ rsassa = kzalloc(sizeof(*rsassa), GFP_KERNEL);
+ if (!rsassa)
+ return ERR_PTR(-ENOMEM);
+
+ ctx.rsassa = rsassa;
+ ctx.data = (unsigned long)data;
+
+ /* Attempt to decode the parameters */
+ ret = asn1_ber_decoder(&rsassa_params_decoder, &ctx, data, datalen);
+ if (ret < 0) {
+ pr_debug("RSASSA parse failed %ld\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ return no_free_ptr(rsassa);
+}
+
+/*
+ * Note an OID when we find one for later processing when we know how
+ * to interpret it.
+ */
+int rsassa_note_OID(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsassa_parse_context *ctx = context;
+
+ ctx->last_oid = look_up_OID(value, vlen);
+ if (ctx->last_oid == OID__NR) {
+ char buffer[56];
+ sprint_oid(value, vlen, buffer, sizeof(buffer));
+ pr_debug("Unknown OID: %s\n", buffer);
+ }
+ return 0;
+}
+
+/*
+ * Parse trailerField. We only accept trailerFieldBC.
+*/
+int rsassa_note_trailer(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ if (vlen != 1 || *(u8 *)value != 0x01) {
+ pr_debug("Unknown trailerField\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int rsassa_note_hash_algo(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsassa_parse_context *ctx = context;
+
+ ctx->rsassa->hash_algo = ctx->last_oid;
+ pr_debug("HASH-ALGO %u %u\n", ctx->rsassa->hash_algo, ctx->params_len);
+ ctx->params = NULL;
+ return 0;
+}
+
+int rsassa_note_maskgen_algo(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsassa_parse_context *ctx = context;
+ int ret;
+
+ ctx->rsassa->maskgen_algo = ctx->last_oid;
+ pr_debug("MGF-ALGO %u %u\n", ctx->rsassa->maskgen_algo, ctx->params_len);
+
+ switch (ctx->rsassa->maskgen_algo) {
+ case OID_id_mgf1:
+ if (!vlen) {
+ pr_debug("MGF1 missing parameters\n");
+ return -EBADMSG;
+ }
+
+ ret = asn1_ber_decoder(&mgf1_params_decoder, ctx,
+ ctx->params, ctx->params_len);
+ if (ret < 0) {
+ pr_debug("MGF1 parse failed %d\n", ret);
+ return ret;
+ }
+ ctx->rsassa->maskgen_hash = ctx->mgf1_last_oid;
+ break;
+
+ default:
+ pr_debug("Unsupported MaskGenAlgorithm %d\n", ret);
+ return -ENOPKG;
+ }
+
+ ctx->params = NULL;
+ return 0;
+}
+
+int rsassa_note_salt_length(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsassa_parse_context *ctx = context;
+ u32 salt_len = 0;
+
+ if (!vlen) {
+ pr_debug("Salt len bad integer\n");
+ return -EBADMSG;
+ }
+ if (vlen > 4) {
+ pr_debug("Salt len too long %zu\n", vlen);
+ return -EBADMSG;
+ }
+ if (((u8 *)value)[0] & 0x80) {
+ pr_debug("Salt len negative\n");
+ return -EBADMSG;
+ }
+
+ for (size_t i = 0; i < vlen; i++) {
+ salt_len <<= 8;
+ salt_len |= ((u8 *)value)[i];
+ }
+
+ ctx->rsassa->salt_len = salt_len;
+ pr_debug("Salt-Len %u\n", salt_len);
+ return 0;
+}
+
+/*
+ * Extract arbitrary parameters.
+ */
+int rsassa_note_params(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsassa_parse_context *ctx = context;
+
+ ctx->params = value - hdrlen;
+ ctx->params_len = vlen + hdrlen;
+ return 0;
+}
+
+/*
+ * Note an OID when we find one for later processing when we know how to
+ * interpret it.
+ */
+int mgf1_note_OID(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct rsassa_parse_context *ctx = context;
+
+ ctx->mgf1_last_oid = look_up_OID(value, vlen);
+ if (ctx->mgf1_last_oid == OID__NR) {
+ char buffer[56];
+ sprint_oid(value, vlen, buffer, sizeof(buffer));
+ pr_debug("Unknown MGF1 OID: %s\n", buffer);
+ }
+ return 0;
+}
+
+/*
+ * Parse the signature parameter block and generate a suitable info string from
+ * it.
+ */
+int rsassa_parse_sig_params(struct public_key_signature *sig,
+ const u8 *sig_params, unsigned int sig_params_size)
+{
+ struct rsassa_parameters *rsassa __free(rsassa_params_free) = NULL;
+ const char *mf, *mh;
+
+ rsassa = rsassa_params_parse(sig_params, sig_params_size);
+ if (IS_ERR(rsassa))
+ return PTR_ERR(rsassa);
+
+ sig->hash_algo = oid_to_hash(rsassa->hash_algo);
+ if (!sig->hash_algo) {
+ pr_notice("Unsupported hash: %u\n", rsassa->hash_algo);
+ return -ENOPKG;
+ }
+
+ switch (rsassa->maskgen_algo) {
+ case OID_id_mgf1:
+ mf = "mgf1";
+ break;
+ default:
+ pr_notice("Unsupported maskgen algo: %u\n", rsassa->maskgen_algo);
+ return -ENOPKG;
+ }
+
+ mh = oid_to_hash(rsassa->maskgen_hash);
+ if (!mh) {
+ pr_notice("Unsupported MGF1 hash: %u\n", rsassa->maskgen_hash);
+ return -ENOPKG;
+ }
+
+ sig->info = kasprintf(GFP_KERNEL, "sighash=%s pss_mask=%s,%s pss_salt=%u",
+ sig->hash_algo, mf, mh, rsassa->salt_len);
+ if (!sig->info)
+ return -ENOMEM;
+ pr_debug("Info string: %s\n", sig->info);
+ return 0;
+}
diff --git a/crypto/asymmetric_keys/rsassa_parser.h b/crypto/asymmetric_keys/rsassa_parser.h
new file mode 100644
index 000000000000..b80401a3de8f
--- /dev/null
+++ b/crypto/asymmetric_keys/rsassa_parser.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* RSASSA-PSS parameter parsing context
+ *
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#include <linux/oid_registry.h>
+
+struct rsassa_parameters {
+ enum OID hash_algo; /* Hash algorithm identifier */
+ enum OID maskgen_algo; /* Mask gen algorithm identifier */
+ enum OID maskgen_hash; /* Mask gen hash algorithm identifier */
+ u32 salt_len;
+};
+
+struct rsassa_parameters *rsassa_params_parse(const void *data, size_t datalen);
+int rsassa_parse_sig_params(struct public_key_signature *sig,
+ const u8 *sig_params, unsigned int sig_params_size);
+
+static inline void rsassa_params_free(struct rsassa_parameters *params)
+{
+ kfree(params);
+}
+DEFINE_FREE(rsassa_params_free, struct rsassa_parameters*, rsassa_params_free(_T))
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index feb9573cacce..453b72eba1fe 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -29,7 +29,7 @@ CertificateSerialNumber ::= INTEGER
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER ({ x509_note_OID }),
- parameters ANY OPTIONAL ({ x509_note_params })
+ parameters ANY OPTIONAL ({ x509_note_algo_id_params })
}
Name ::= SEQUENCE OF RelativeDistinguishedName
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 5ab5b4e5f1b4..6c431bf181f2 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -15,28 +15,7 @@
#include "x509_parser.h"
#include "x509.asn1.h"
#include "x509_akid.asn1.h"
-
-struct x509_parse_context {
- struct x509_certificate *cert; /* Certificate being constructed */
- unsigned long data; /* Start of data */
- const void *key; /* Key data */
- size_t key_size; /* Size of key data */
- const void *params; /* Key parameters */
- size_t params_size; /* Size of key parameters */
- enum OID key_algo; /* Algorithm used by the cert's key */
- enum OID last_oid; /* Last OID encountered */
- enum OID sig_algo; /* Algorithm used to sign the cert */
- u8 o_size; /* Size of organizationName (O) */
- u8 cn_size; /* Size of commonName (CN) */
- u8 email_size; /* Size of emailAddress */
- u16 o_offset; /* Offset of organizationName (O) */
- u16 cn_offset; /* Offset of commonName (CN) */
- u16 email_offset; /* Offset of emailAddress */
- unsigned raw_akid_size;
- const void *raw_akid; /* Raw authorityKeyId in ASN.1 */
- const void *akid_raw_issuer; /* Raw directoryName in authorityKeyId */
- unsigned akid_raw_issuer_size;
-};
+#include "rsassa_parser.h"
/*
* Free an X.509 certificate
@@ -104,15 +83,15 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
cert->pub->keylen = ctx->key_size;
- cert->pub->params = kmemdup(ctx->params, ctx->params_size, GFP_KERNEL);
+ cert->pub->params = kmemdup(ctx->key_params, ctx->key_params_size, GFP_KERNEL);
if (!cert->pub->params)
return ERR_PTR(-ENOMEM);
- cert->pub->paramlen = ctx->params_size;
+ cert->pub->paramlen = ctx->key_params_size;
cert->pub->algo = ctx->key_algo;
/* Grab the signature bits */
- ret = x509_get_sig_params(cert);
+ ret = x509_get_sig_params(cert, ctx);
if (ret < 0)
return ERR_PTR(ret);
@@ -146,7 +125,7 @@ int x509_note_OID(void *context, size_t hdrlen,
ctx->last_oid = look_up_OID(value, vlen);
if (ctx->last_oid == OID__NR) {
- char buffer[50];
+ char buffer[56];
sprint_oid(value, vlen, buffer, sizeof(buffer));
pr_debug("Unknown OID: [%lu] %s\n",
(unsigned long)value - ctx->data, buffer);
@@ -179,6 +158,7 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
+ int err;
pr_debug("PubKey Algo: %u\n", ctx->last_oid);
@@ -210,6 +190,9 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
ctx->cert->sig->hash_algo = "sha1";
goto ecdsa;
+ case OID_id_rsassa_pss:
+ goto rsassa_pss;
+
case OID_id_rsassa_pkcs1_v1_5_with_sha3_256:
ctx->cert->sig->hash_algo = "sha3-256";
goto rsa_pkcs1;
@@ -268,6 +251,24 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
goto ml_dsa;
}
+rsassa_pss:
+ if (!ctx->algo_params || !ctx->algo_params_size) {
+ pr_debug("RSASSA-PSS sig algo without parameters\n");
+ return -EBADMSG;
+ }
+
+ err = rsassa_parse_sig_params(ctx->cert->sig,
+ ctx->algo_params, ctx->algo_params_size);
+ if (err < 0)
+ return err;
+
+ ctx->cert->sig->pkey_algo = "rsa";
+ ctx->cert->sig->encoding = "emsa-pss";
+ ctx->sig_algo = ctx->last_oid;
+ ctx->algo_params = NULL;
+ ctx->algo_params_size = 0;
+ return 0;
+
rsa_pkcs1:
ctx->cert->sig->pkey_algo = "rsa";
ctx->cert->sig->encoding = "pkcs1";
@@ -324,8 +325,8 @@ int x509_note_signature(void *context, size_t hdrlen,
vlen--;
}
- ctx->cert->raw_sig = value;
- ctx->cert->raw_sig_size = vlen;
+ ctx->sig = value;
+ ctx->sig_size = vlen;
return 0;
}
@@ -479,23 +480,16 @@ int x509_note_subject(void *context, size_t hdrlen,
}
/*
- * Extract the parameters for the public key
+ * Extract the parameters for an AlgorithmIdentifier.
*/
-int x509_note_params(void *context, size_t hdrlen,
- unsigned char tag,
- const void *value, size_t vlen)
+int x509_note_algo_id_params(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
- /*
- * AlgorithmIdentifier is used three times in the x509, we should skip
- * first and ignore third, using second one which is after subject and
- * before subjectPublicKey.
- */
- if (!ctx->cert->raw_subject || ctx->key)
- return 0;
- ctx->params = value - hdrlen;
- ctx->params_size = vlen + hdrlen;
+ ctx->algo_params = value - hdrlen;
+ ctx->algo_params_size = vlen + hdrlen;
return 0;
}
@@ -514,12 +508,28 @@ int x509_extract_key_data(void *context, size_t hdrlen,
case OID_rsaEncryption:
ctx->cert->pub->pkey_algo = "rsa";
break;
+ case OID_id_rsassa_pss:
+ /* Parameters are optional for the key itself. */
+ if (ctx->algo_params_size) {
+ struct rsassa_parameters *params __free(rsassa_params_free) = NULL;
+ ctx->key_params = ctx->algo_params;
+ ctx->key_params_size = ctx->algo_params_size;
+ ctx->algo_params = NULL;
+ ctx->algo_params_size = 0;
+
+ params = rsassa_params_parse(ctx->key_params, ctx->key_params_size);
+ if (IS_ERR(params))
+ return PTR_ERR(params);
+ break;
+ }
+ ctx->cert->pub->pkey_algo = "rsa";
+ break;
case OID_gost2012PKey256:
case OID_gost2012PKey512:
ctx->cert->pub->pkey_algo = "ecrdsa";
break;
case OID_id_ecPublicKey:
- if (parse_OID(ctx->params, ctx->params_size, &oid) != 0)
+ if (parse_OID(ctx->algo_params, ctx->algo_params_size, &oid) != 0)
return -EBADMSG;
switch (oid) {
@@ -557,6 +567,8 @@ int x509_extract_key_data(void *context, size_t hdrlen,
return -EBADMSG;
ctx->key = value + 1;
ctx->key_size = vlen - 1;
+ ctx->algo_params = NULL;
+ ctx->algo_params_size = 0;
return 0;
}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 0688c222806b..be2e1f6cb9f5 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -23,8 +23,6 @@ struct x509_certificate {
time64_t valid_to;
const void *tbs; /* Signed data */
unsigned tbs_size; /* Size of signed data */
- unsigned raw_sig_size; /* Size of signature */
- const void *raw_sig; /* Signature data */
const void *raw_serial; /* Raw serial number in ASN.1 */
unsigned raw_serial_size;
unsigned raw_issuer_size;
@@ -41,6 +39,34 @@ struct x509_certificate {
bool blacklisted;
};
+struct x509_parse_context {
+ struct x509_certificate *cert; /* Certificate being constructed */
+ unsigned long data; /* Start of data */
+ const void *key; /* Key data */
+ size_t key_size; /* Size of key data */
+ const void *algo_params; /* AlgorithmIdentifier: parameters */
+ size_t algo_params_size; /* AlgorithmIdentifier: parameters size */
+ const void *key_params; /* Key parameters */
+ size_t key_params_size; /* Size of key parameters */
+ const void *sig_params; /* Signature parameters */
+ unsigned int sig_params_size; /* Size of sig parameters */
+ unsigned int sig_size; /* Size of signature */
+ const void *sig; /* Signature data */
+ enum OID key_algo; /* Algorithm used by the cert's key */
+ enum OID last_oid; /* Last OID encountered */
+ enum OID sig_algo; /* Algorithm used to sign the cert */
+ u8 o_size; /* Size of organizationName (O) */
+ u8 cn_size; /* Size of commonName (CN) */
+ u8 email_size; /* Size of emailAddress */
+ u16 o_offset; /* Offset of organizationName (O) */
+ u16 cn_offset; /* Offset of commonName (CN) */
+ u16 email_offset; /* Offset of emailAddress */
+ unsigned raw_akid_size;
+ const void *raw_akid; /* Raw authorityKeyId in ASN.1 */
+ const void *akid_raw_issuer; /* Raw directoryName in authorityKeyId */
+ unsigned akid_raw_issuer_size;
+};
+
/*
* x509_cert_parser.c
*/
@@ -55,5 +81,6 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen,
/*
* x509_public_key.c
*/
-extern int x509_get_sig_params(struct x509_certificate *cert);
+extern const char *oid_to_hash(enum OID oid);
+extern int x509_get_sig_params(struct x509_certificate *cert, struct x509_parse_context *parse);
extern int x509_check_for_self_signed(struct x509_certificate *cert);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 12e3341e806b..b2f8542accc4 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -17,11 +17,32 @@
#include "asymmetric_keys.h"
#include "x509_parser.h"
+/*
+ * Translate OIDs to hash algorithm names.
+ */
+const char *oid_to_hash(enum OID oid)
+{
+ switch (oid) {
+ case OID_sha1: return "sha1";
+ case OID_sha256: return "sha256";
+ case OID_sha384: return "sha384";
+ case OID_sha512: return "sha512";
+ case OID_sha224: return "sha224";
+ case OID_sm3: return "sm3";
+ case OID_gost2012Digest256: return "streebog256";
+ case OID_gost2012Digest512: return "streebog512";
+ case OID_sha3_256: return "sha3-256";
+ case OID_sha3_384: return "sha3-384";
+ case OID_sha3_512: return "sha3-512";
+ default: return NULL;
+ }
+}
+
/*
* Set up the signature parameters in an X.509 certificate. This involves
* digesting the signed data and extracting the signature.
*/
-int x509_get_sig_params(struct x509_certificate *cert)
+int x509_get_sig_params(struct x509_certificate *cert, struct x509_parse_context *parse)
{
struct public_key_signature *sig = cert->sig;
struct crypto_shash *tfm;
@@ -31,11 +52,11 @@ int x509_get_sig_params(struct x509_certificate *cert)
pr_devel("==>%s()\n", __func__);
- sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
+ sig->s = kmemdup(parse->sig, parse->sig_size, GFP_KERNEL);
if (!sig->s)
return -ENOMEM;
- sig->s_size = cert->raw_sig_size;
+ sig->s_size = parse->sig_size;
/* Allocate the hashing algorithm we're going to need and find out how
* big the hash operational data will be.
@@ -43,6 +64,7 @@ int x509_get_sig_params(struct x509_certificate *cert)
tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
if (IS_ERR(tfm)) {
if (PTR_ERR(tfm) == -ENOENT) {
+ pr_debug("Unsupported hash %s\n", sig->hash_algo);
cert->unsupported_sig = true;
return 0;
}
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index 30821a6a4f72..d546ea7999b9 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -31,6 +31,8 @@ enum OID {
/* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */
OID_rsaEncryption, /* 1.2.840.113549.1.1.1 */
OID_sha1WithRSAEncryption, /* 1.2.840.113549.1.1.5 */
+ OID_id_mgf1, /* 1.2.840.113549.1.1.8 */
+ OID_id_rsassa_pss, /* 1.2.840.113549.1.1.10 */
OID_sha256WithRSAEncryption, /* 1.2.840.113549.1.1.11 */
OID_sha384WithRSAEncryption, /* 1.2.840.113549.1.1.12 */
OID_sha512WithRSAEncryption, /* 1.2.840.113549.1.1.13 */
^ permalink raw reply related
* [PATCH v11 8/8] modsign: Enable RSASSA-PSS module signing
From: David Howells @ 2026-01-05 15:21 UTC (permalink / raw)
To: Lukas Wunner, Ignat Korchagin
Cc: David Howells, 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: <20260105152145.1801972-1-dhowells@redhat.com>
Add support for RSASSA-PSS signatures (RFC8017) for use with module signing
and other public key cryptography done by the kernel.
Note that only signature verification is supported by the kernel.
Note further that this alters some of the same code as the MLDSA support,
so that needs to be applied first to avoid conflicts.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
---
certs/Kconfig | 6 ++++++
certs/Makefile | 1 +
scripts/sign-file.c | 39 +++++++++++++++++++++++++++++++++++++--
3 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/certs/Kconfig b/certs/Kconfig
index 94b086684d07..beb8991ad761 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -27,6 +27,12 @@ config MODULE_SIG_KEY_TYPE_RSA
help
Use an RSA key for module signing.
+config MODULE_SIG_KEY_TYPE_RSASSA_PSS
+ bool "RSASSA-PSS"
+ select CRYPTO_RSA
+ help
+ Use an RSASSA-PSS key for module signing.
+
config MODULE_SIG_KEY_TYPE_ECDSA
bool "ECDSA"
select CRYPTO_ECDSA
diff --git a/certs/Makefile b/certs/Makefile
index 3ee1960f9f4a..3b5a3a303f4c 100644
--- a/certs/Makefile
+++ b/certs/Makefile
@@ -42,6 +42,7 @@ targets += x509_certificate_list
# boolean option and we unfortunately can't make it depend on !RANDCONFIG.
ifeq ($(CONFIG_MODULE_SIG_KEY),certs/signing_key.pem)
+keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_RSASSA_PSS) := -newkey rsassa-pss
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_ECDSA) := -newkey ec -pkeyopt ec_paramgen_curve:secp384r1
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_44) := -newkey ml-dsa-44
keytype-$(CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_65) := -newkey ml-dsa-65
diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index b726581075f9..ca605095194e 100644
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -233,6 +233,7 @@ int main(int argc, char **argv)
EVP_PKEY *private_key;
#ifndef USE_PKCS7
CMS_ContentInfo *cms = NULL;
+ CMS_SignerInfo *signer;
unsigned int use_keyid = 0;
#else
PKCS7 *pkcs7 = NULL;
@@ -329,13 +330,47 @@ int main(int argc, char **argv)
!EVP_PKEY_is_a(private_key, "ML-DSA-65") &&
!EVP_PKEY_is_a(private_key, "ML-DSA-87"))
flags |= use_signed_attrs;
+ if (EVP_PKEY_is_a(private_key, "RSASSA-PSS"))
+ flags |= CMS_KEY_PARAM;
+ if (EVP_PKEY_is_a(private_key, "RSASSA-PSS")) {
+ EVP_PKEY_CTX *pkctx;
+ char mdname[1024] = {};
+
+ pkctx = EVP_PKEY_CTX_new(private_key, NULL);
+
+ ERR(!EVP_PKEY_sign_init(pkctx), "EVP_PKEY_sign_init");
+ ERR(!EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING),
+ "EVP_PKEY_CTX_set_rsa_padding");
+ ERR(!EVP_PKEY_CTX_set_rsa_mgf1_md_name(pkctx, hash_algo, NULL),
+ "EVP_PKEY_CTX_set_rsa_mgf1_md_name");
+
+ ERR(!EVP_PKEY_CTX_get_rsa_mgf1_md_name(pkctx, mdname, sizeof(mdname)),
+ "EVP_PKEY_CTX_get_rsa_mgf1_md_name");
+ printf("RSASSA-PSS %s\n", mdname);
+ }
/* Load the signature message from the digest buffer. */
cms = CMS_sign(NULL, NULL, NULL, NULL, flags);
ERR(!cms, "CMS_sign");
- ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo, flags),
- "CMS_add1_signer");
+ signer = CMS_add1_signer(cms, x509, private_key, digest_algo, flags);
+ ERR(!signer, "CMS_add1_signer");
+
+ if (EVP_PKEY_is_a(private_key, "RSASSA-PSS")) {
+ EVP_PKEY_CTX *pkctx;
+ char mdname[1024] = {};
+
+ pkctx = CMS_SignerInfo_get0_pkey_ctx(signer);
+ ERR(!EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING),
+ "EVP_PKEY_CTX_set_rsa_padding");
+ ERR(!EVP_PKEY_CTX_set_rsa_mgf1_md_name(pkctx, hash_algo, NULL),
+ "EVP_PKEY_CTX_set_rsa_mgf1_md_name");
+
+ ERR(!EVP_PKEY_CTX_get_rsa_mgf1_md_name(pkctx, mdname, sizeof(mdname)),
+ "EVP_PKEY_CTX_get_rsa_mgf1_md_name");
+ printf("RSASSA-PSS %s\n", mdname);
+ }
+
ERR(CMS_final(cms, bm, NULL, flags) != 1,
"CMS_final");
^ permalink raw reply related
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Yury Norov @ 2026-01-05 16:36 UTC (permalink / raw)
To: Jani Nikula
Cc: Andy Shevchenko, Joel Fernandes, Steven Rostedt, Andrew Morton,
Masami Hiramatsu, Mathieu Desnoyers, Christophe Leroy,
Randy Dunlap, Ingo Molnar, Joonas Lahtinen, David Laight,
Petr Pavlu, Andi Shyti, Rodrigo Vivi, Tvrtko Ursulin,
Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, linux-kernel, intel-gfx, dri-devel,
linux-modules, linux-trace-kernel
In-Reply-To: <254c1096c3b892923dd12b07a8b80291b88c0e9b@intel.com>
On Mon, Jan 05, 2026 at 11:29:51AM +0200, Jani Nikula wrote:
> On Sat, 03 Jan 2026, Yury Norov <yury.norov@gmail.com> wrote:
> > On Sat, Jan 03, 2026 at 02:57:58PM +0200, Andy Shevchenko wrote:
> >> On Fri, Jan 02, 2026 at 07:50:59PM -0500, Joel Fernandes wrote:
> >> > On Mon, Dec 29, 2025 at 11:17:48AM -0500, Steven Rostedt wrote:
> >>
> >> ...
> >>
> >> > I use trace_printk() all the time for kernel, particularly RCU development.
> >> > One of the key usecases I have is dumping traces on panic (with panic on warn
> >> > and stop tracing on warn enabled). This is extremely useful since I can add
> >> > custom tracing and dump traces when rare conditions occur. I fixed several
> >> > bugs with this technique.
> >> >
> >> > I also recommend keeping it convenient to use.
> >>
> >> Okay, you know C, please share your opinion what header is the best to hold the
> >> trace_printk.h to be included.
> >
> > What if we include it on Makefile level, similarly to how W=1 works?
> >
> > make D=1 // trace_printk() is available
> > make D=0 // trace_printk() is not available
> > make // trace_printk() is not available
> >
> > Where D stands for debugging.
> >
> > D=1 may be a default setting if you prefer, but the most important is
> > that every compilation unit will have an access to debugging without
> > polluting core headers.
>
> You do realize this means recompiling everything when adding D=1 for
> debugging?
Yes sir I do.
It would be as simple (or hard) as building another arch:
make O=../build/linux-arm64
make O=../build/linux-x86_64
make D=1 W=1 O=../build/linux-x86_64-dev
If you're both developer and CI engineer in your company, you're likely
already doing something like that. If you're CI-only, there're no
changes for you. If you're a developer - yeah, you'd have to learn a
new flag.
The real problem of course is the status inflation. The fact that
defconfig enables CONFIG_EXPERT and CONFIG_DEBUG_KERNEL implies that
every random person who is able to do:
git clone && make && sudo make install
now assumed an expert kernel user and active developer. It is not
correct, and it leads to bloating kernel with dev-only features.
What we discuss here is a new marker for those real experts and
developers, I think. (In an hope that it will inflate not very fast.)
Thanks,
Yury
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Steven Rostedt @ 2026-01-05 16:39 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Joel Fernandes, Andrew Morton, Yury Norov, Masami Hiramatsu,
Mathieu Desnoyers, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Vivi Rodrigo, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, linux-modules@vger.kernel.org,
linux-trace-kernel@vger.kernel.org
In-Reply-To: <aVmyZ0iXzTkNU86y@smile.fi.intel.com>
On Sun, 4 Jan 2026 02:20:55 +0200
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> >
> > I do not think it is necessary to move it.
>
> I'm not talking about move, I'm talking about the C 101 thingy. Any custom API
> should be included before use, otherwise compiler won't see it. Which header do
> you want to include to have this API being provided? Note, it's really bad
> situation right now with the header to be included implicitly via non-obvious
> or obscure path. The discussion moved as far as I see it towards the finding a
> good place for the trace_printk.h.
It's not a normal API. It's for debugging the kernel. Thus it should be
available everywhere without having to add a header. Hence, the best place
to include trace_printk.h, is in kernel.h.
I'm thinking that my proposed config option is the best solution now. For
those that do not care about debugging the kernel, you enable the
"HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
everyone else, it will not slow down their workflow when they need to debug
code.
-- Steve
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Steven Rostedt @ 2026-01-05 16:50 UTC (permalink / raw)
To: Yury Norov
Cc: Jani Nikula, Andy Shevchenko, Joel Fernandes, Andrew Morton,
Masami Hiramatsu, Mathieu Desnoyers, Christophe Leroy,
Randy Dunlap, Ingo Molnar, Joonas Lahtinen, David Laight,
Petr Pavlu, Andi Shyti, Rodrigo Vivi, Tvrtko Ursulin,
Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, linux-kernel, intel-gfx, dri-devel,
linux-modules, linux-trace-kernel
In-Reply-To: <aVvoe5fQN3EUtEAJ@yury>
On Mon, 5 Jan 2026 11:36:11 -0500
Yury Norov <yury.norov@gmail.com> wrote:
> > You do realize this means recompiling everything when adding D=1 for
> > debugging?
>
> Yes sir I do.
>
> It would be as simple (or hard) as building another arch:
>
> make O=../build/linux-arm64
> make O=../build/linux-x86_64
> make D=1 W=1 O=../build/linux-x86_64-dev
>
> If you're both developer and CI engineer in your company, you're likely
> already doing something like that. If you're CI-only, there're no
> changes for you. If you're a developer - yeah, you'd have to learn a
> new flag.
I'm saying this right now.
Hard-nacked-by: Steven Rostedt <rostedt@goodmis.org>
Why do you want to burden developers?
>
> The real problem of course is the status inflation. The fact that
> defconfig enables CONFIG_EXPERT and CONFIG_DEBUG_KERNEL implies that
> every random person who is able to do:
>
> git clone && make && sudo make install
>
> now assumed an expert kernel user and active developer. It is not
> correct, and it leads to bloating kernel with dev-only features.
>
> What we discuss here is a new marker for those real experts and
> developers, I think. (In an hope that it will inflate not very fast.)
This is a generic feature that helps all developers. The ones spending the
most time in maintaining the kernel.
Add the config I mentioned:
config HIDE_TRACE_PRINTK
depends on TRACING
help
trace_printk() is an extremely powerful utility to debug and develop
kernel code. It is defined in kernel.h so that it can be easily accessed
during development or having to debug existing code.
But trace_printk() is not to be included in the final result, and having
it in kernel.h during normal builds where the builder has no plans of
debugging the kernel causes wasted cycles and time in compiling the kernel.
By saying yes here, the include of trace_printk() macros will be hidden
from kernel.h and help speed up the compile.
If you do not plan on debugging this kernel, say Y
It is default 'n' as the normal person building their own kernel likely
wants to debug it. Once you set this to 'y' then you get your "fast" builds.
Then in kernel.h have:
#ifndef CONFIG_HIDE_TRACE_PRINTK
# include <linux/trace_printk.h>
#endif
-- Steve
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Joel Fernandes @ 2026-01-05 17:11 UTC (permalink / raw)
To: Steven Rostedt, Andy Shevchenko
Cc: Andrew Morton, Yury Norov, Masami Hiramatsu, Mathieu Desnoyers,
Christophe Leroy, Randy Dunlap, Ingo Molnar, Jani Nikula,
Joonas Lahtinen, David Laight, Petr Pavlu, Andi Shyti,
Vivi Rodrigo, Tvrtko Ursulin, Daniel Gomez, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich, linux-kernel@vger.kernel.org,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-modules@vger.kernel.org, linux-trace-kernel@vger.kernel.org
In-Reply-To: <20260105113902.6bdfcfa8@gandalf.local.home>
On 1/5/2026 11:39 AM, Steven Rostedt wrote:
> On Sun, 4 Jan 2026 02:20:55 +0200
> Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>
>>>
>>> I do not think it is necessary to move it.
>>
>> I'm not talking about move, I'm talking about the C 101 thingy. Any custom API
>> should be included before use, otherwise compiler won't see it. Which header do
>> you want to include to have this API being provided? Note, it's really bad
>> situation right now with the header to be included implicitly via non-obvious
>> or obscure path. The discussion moved as far as I see it towards the finding a
>> good place for the trace_printk.h.
>
> It's not a normal API. It's for debugging the kernel. Thus it should be
> available everywhere without having to add a header. Hence, the best place
> to include trace_printk.h, is in kernel.h.
>
> I'm thinking that my proposed config option is the best solution now. For
> those that do not care about debugging the kernel, you enable the
> "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
> everyone else, it will not slow down their workflow when they need to debug
> code.
100% agree. We do have people running custom configs for faster builds, so this
hide thing could be enabled there assuming those don't care about debug.
In other words, "If it aint broke, don't fix it".
- Joel
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Andy Shevchenko @ 2026-01-05 18:02 UTC (permalink / raw)
To: Steven Rostedt
Cc: Joel Fernandes, Andrew Morton, Yury Norov, Masami Hiramatsu,
Mathieu Desnoyers, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Vivi Rodrigo, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, linux-modules@vger.kernel.org,
linux-trace-kernel@vger.kernel.org
In-Reply-To: <20260105113902.6bdfcfa8@gandalf.local.home>
On Mon, Jan 05, 2026 at 11:39:02AM -0500, Steven Rostedt wrote:
> On Sun, 4 Jan 2026 02:20:55 +0200
> Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>
> > > I do not think it is necessary to move it.
> >
> > I'm not talking about move, I'm talking about the C 101 thingy. Any custom API
> > should be included before use, otherwise compiler won't see it. Which header do
> > you want to include to have this API being provided? Note, it's really bad
> > situation right now with the header to be included implicitly via non-obvious
> > or obscure path. The discussion moved as far as I see it towards the finding a
> > good place for the trace_printk.h.
>
> It's not a normal API. It's for debugging the kernel. Thus it should be
> available everywhere without having to add a header. Hence, the best place
> to include trace_printk.h, is in kernel.h.
With the above it sounds like you rather want to see it being included as
kconfig.h (to every single file). But I disagree on that approach, why do
we need this header to pollute every file even if I do not debug the thing?
But since the current state is kernel.h, the status quo is to keep it there
for now.
> I'm thinking that my proposed config option is the best solution now. For
> those that do not care about debugging the kernel, you enable the
> "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
> everyone else, it will not slow down their workflow when they need to debug
> code.
Maybe, to keep a status quo.
Seems for now the compromise is to have it split and be included back to
kernel.h and later we can decide if the option or other variants can give a
better granularity for people who are not lazy to remember and add a header if
they need to debug stuff.
Yury, I think in v5 you need to drop this patch, otherwise we won't move further.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Yury Norov @ 2026-01-05 18:07 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Steven Rostedt, Joel Fernandes, Andrew Morton, Masami Hiramatsu,
Mathieu Desnoyers, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Vivi Rodrigo, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, linux-modules@vger.kernel.org,
linux-trace-kernel@vger.kernel.org
In-Reply-To: <aVv8vwtGFhssitxG@smile.fi.intel.com>
On Mon, Jan 05, 2026 at 08:02:39PM +0200, Andy Shevchenko wrote:
> On Mon, Jan 05, 2026 at 11:39:02AM -0500, Steven Rostedt wrote:
> > On Sun, 4 Jan 2026 02:20:55 +0200
> > Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> >
> > > > I do not think it is necessary to move it.
> > >
> > > I'm not talking about move, I'm talking about the C 101 thingy. Any custom API
> > > should be included before use, otherwise compiler won't see it. Which header do
> > > you want to include to have this API being provided? Note, it's really bad
> > > situation right now with the header to be included implicitly via non-obvious
> > > or obscure path. The discussion moved as far as I see it towards the finding a
> > > good place for the trace_printk.h.
> >
> > It's not a normal API. It's for debugging the kernel. Thus it should be
> > available everywhere without having to add a header. Hence, the best place
> > to include trace_printk.h, is in kernel.h.
>
> With the above it sounds like you rather want to see it being included as
> kconfig.h (to every single file). But I disagree on that approach, why do
> we need this header to pollute every file even if I do not debug the thing?
>
> But since the current state is kernel.h, the status quo is to keep it there
> for now.
>
> > I'm thinking that my proposed config option is the best solution now. For
> > those that do not care about debugging the kernel, you enable the
> > "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
> > everyone else, it will not slow down their workflow when they need to debug
> > code.
>
> Maybe, to keep a status quo.
+1
> Seems for now the compromise is to have it split and be included back to
> kernel.h and later we can decide if the option or other variants can give a
> better granularity for people who are not lazy to remember and add a header if
> they need to debug stuff.
>
> Yury, I think in v5 you need to drop this patch, otherwise we won't move further.
Not sure we need v5 because the only change is dropping the last patch
in the series. But if you prefer - I can send v5.
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Andy Shevchenko @ 2026-01-05 18:11 UTC (permalink / raw)
To: Yury Norov
Cc: Steven Rostedt, Joel Fernandes, Andrew Morton, Masami Hiramatsu,
Mathieu Desnoyers, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Vivi Rodrigo, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, linux-modules@vger.kernel.org,
linux-trace-kernel@vger.kernel.org
In-Reply-To: <aVv946dXQfOifz5O@yury>
On Mon, Jan 05, 2026 at 01:07:31PM -0500, Yury Norov wrote:
> On Mon, Jan 05, 2026 at 08:02:39PM +0200, Andy Shevchenko wrote:
> > On Mon, Jan 05, 2026 at 11:39:02AM -0500, Steven Rostedt wrote:
...
> > Yury, I think in v5 you need to drop this patch, otherwise we won't move further.
>
> Not sure we need v5 because the only change is dropping the last patch
> in the series. But if you prefer - I can send v5.
It depends on who is going to apply them. For me personally v5 is not needed,
but I think there were some tags given in v4? With that it might make some
sense to have a v5.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Christophe Leroy (CS GROUP) @ 2026-01-05 18:21 UTC (permalink / raw)
To: Joel Fernandes, Steven Rostedt, Andy Shevchenko
Cc: Andrew Morton, Yury Norov, Masami Hiramatsu, Mathieu Desnoyers,
Randy Dunlap, Ingo Molnar, Jani Nikula, Joonas Lahtinen,
David Laight, Petr Pavlu, Andi Shyti, Vivi Rodrigo,
Tvrtko Ursulin, Daniel Gomez, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich, linux-kernel@vger.kernel.org,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-modules@vger.kernel.org, linux-trace-kernel@vger.kernel.org
In-Reply-To: <d642ef4c-145c-4b16-818d-153c8f2e3485@nvidia.com>
Le 05/01/2026 à 18:11, Joel Fernandes a écrit :
>
>
> On 1/5/2026 11:39 AM, Steven Rostedt wrote:
>> On Sun, 4 Jan 2026 02:20:55 +0200
>> Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>>
>>>>
>>>> I do not think it is necessary to move it.
>>>
>>> I'm not talking about move, I'm talking about the C 101 thingy. Any custom API
>>> should be included before use, otherwise compiler won't see it. Which header do
>>> you want to include to have this API being provided? Note, it's really bad
>>> situation right now with the header to be included implicitly via non-obvious
>>> or obscure path. The discussion moved as far as I see it towards the finding a
>>> good place for the trace_printk.h.
>>
>> It's not a normal API. It's for debugging the kernel. Thus it should be
>> available everywhere without having to add a header. Hence, the best place
>> to include trace_printk.h, is in kernel.h.
>>
>> I'm thinking that my proposed config option is the best solution now. For
>> those that do not care about debugging the kernel, you enable the
>> "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
>> everyone else, it will not slow down their workflow when they need to debug
>> code.
>
> 100% agree. We do have people running custom configs for faster builds, so this
> hide thing could be enabled there assuming those don't care about debug.
>
> In other words, "If it aint broke, don't fix it".
But if I understand correctly, it would save 2% build time. That means
12 secondes on a 10 minutes build. Is it really worth it ?
Christophe
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Jani Nikula @ 2026-01-05 18:30 UTC (permalink / raw)
To: Yury Norov
Cc: Andy Shevchenko, Joel Fernandes, Steven Rostedt, Andrew Morton,
Masami Hiramatsu, Mathieu Desnoyers, Christophe Leroy,
Randy Dunlap, Ingo Molnar, Joonas Lahtinen, David Laight,
Petr Pavlu, Andi Shyti, Rodrigo Vivi, Tvrtko Ursulin,
Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, linux-kernel, intel-gfx, dri-devel,
linux-modules, linux-trace-kernel
In-Reply-To: <aVvoe5fQN3EUtEAJ@yury>
On Mon, 05 Jan 2026, Yury Norov <yury.norov@gmail.com> wrote:
> On Mon, Jan 05, 2026 at 11:29:51AM +0200, Jani Nikula wrote:
>> On Sat, 03 Jan 2026, Yury Norov <yury.norov@gmail.com> wrote:
>> > On Sat, Jan 03, 2026 at 02:57:58PM +0200, Andy Shevchenko wrote:
>> >> On Fri, Jan 02, 2026 at 07:50:59PM -0500, Joel Fernandes wrote:
>> >> > On Mon, Dec 29, 2025 at 11:17:48AM -0500, Steven Rostedt wrote:
>> >>
>> >> ...
>> >>
>> >> > I use trace_printk() all the time for kernel, particularly RCU development.
>> >> > One of the key usecases I have is dumping traces on panic (with panic on warn
>> >> > and stop tracing on warn enabled). This is extremely useful since I can add
>> >> > custom tracing and dump traces when rare conditions occur. I fixed several
>> >> > bugs with this technique.
>> >> >
>> >> > I also recommend keeping it convenient to use.
>> >>
>> >> Okay, you know C, please share your opinion what header is the best to hold the
>> >> trace_printk.h to be included.
>> >
>> > What if we include it on Makefile level, similarly to how W=1 works?
>> >
>> > make D=1 // trace_printk() is available
>> > make D=0 // trace_printk() is not available
>> > make // trace_printk() is not available
>> >
>> > Where D stands for debugging.
>> >
>> > D=1 may be a default setting if you prefer, but the most important is
>> > that every compilation unit will have an access to debugging without
>> > polluting core headers.
>>
>> You do realize this means recompiling everything when adding D=1 for
>> debugging?
>
> Yes sir I do.
>
> It would be as simple (or hard) as building another arch:
>
> make O=../build/linux-arm64
> make O=../build/linux-x86_64
> make D=1 W=1 O=../build/linux-x86_64-dev
>
> If you're both developer and CI engineer in your company, you're likely
> already doing something like that. If you're CI-only, there're no
> changes for you. If you're a developer - yeah, you'd have to learn a
> new flag.
Learn a new flag?
What I'm saying is, if you're doing regular builds as a developer, and
*then* realize you need trace_printk(), doing your suggested 'make D=1'
rebuilds *everything*. Not exactly something you want in the middle of
your development flow.
I'd *rather* manually add that #include where needed, and rebuild just
those files. I don't even feel very strongly about the whole thing,
other than the D=1 being the worst suggestion so far in the thread.
BR,
Jani.
>
> The real problem of course is the status inflation. The fact that
> defconfig enables CONFIG_EXPERT and CONFIG_DEBUG_KERNEL implies that
> every random person who is able to do:
>
> git clone && make && sudo make install
>
> now assumed an expert kernel user and active developer. It is not
> correct, and it leads to bloating kernel with dev-only features.
>
> What we discuss here is a new marker for those real experts and
> developers, I think. (In an hope that it will inflate not very fast.)
>
> Thanks,
> Yury
--
Jani Nikula, Intel
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Joel Fernandes @ 2026-01-05 19:33 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP), Steven Rostedt, Andy Shevchenko
Cc: Andrew Morton, Yury Norov, Masami Hiramatsu, Mathieu Desnoyers,
Randy Dunlap, Ingo Molnar, Jani Nikula, Joonas Lahtinen,
David Laight, Petr Pavlu, Andi Shyti, Vivi Rodrigo,
Tvrtko Ursulin, Daniel Gomez, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich, linux-kernel@vger.kernel.org,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-modules@vger.kernel.org, linux-trace-kernel@vger.kernel.org
In-Reply-To: <63a00906-a5c6-43de-82ce-328c8eaa7d3f@kernel.org>
On 1/5/2026 1:21 PM, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 05/01/2026 à 18:11, Joel Fernandes a écrit :
>>
>>
>> On 1/5/2026 11:39 AM, Steven Rostedt wrote:
>>> On Sun, 4 Jan 2026 02:20:55 +0200
>>> Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>>>
>>>>>
>>>>> I do not think it is necessary to move it.
>>>>
>>>> I'm not talking about move, I'm talking about the C 101 thingy. Any custom API
>>>> should be included before use, otherwise compiler won't see it. Which header do
>>>> you want to include to have this API being provided? Note, it's really bad
>>>> situation right now with the header to be included implicitly via non-obvious
>>>> or obscure path. The discussion moved as far as I see it towards the finding a
>>>> good place for the trace_printk.h.
>>>
>>> It's not a normal API. It's for debugging the kernel. Thus it should be
>>> available everywhere without having to add a header. Hence, the best place
>>> to include trace_printk.h, is in kernel.h.
>>>
>>> I'm thinking that my proposed config option is the best solution now. For
>>> those that do not care about debugging the kernel, you enable the
>>> "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
>>> everyone else, it will not slow down their workflow when they need to debug
>>> code.
>>
>> 100% agree. We do have people running custom configs for faster builds, so this
>> hide thing could be enabled there assuming those don't care about debug.
>>
>> In other words, "If it aint broke, don't fix it".
>
> But if I understand correctly, it would save 2% build time. That means 12
> secondes on a 10 minutes build. Is it really worth it ?
>
99% of my kernel builds are usually 90 seconds. I throw a lot of cores at it and
with ccache. I care more about trace_printk not being available than saving 2%.
But YMMV. I am sure there are people who care a lot about build time, but for me
it has not (yet) been a problem.
- Joel
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Steven Rostedt @ 2026-01-05 20:04 UTC (permalink / raw)
To: Joel Fernandes
Cc: Christophe Leroy (CS GROUP), Andy Shevchenko, Andrew Morton,
Yury Norov, Masami Hiramatsu, Mathieu Desnoyers, Randy Dunlap,
Ingo Molnar, Jani Nikula, Joonas Lahtinen, David Laight,
Petr Pavlu, Andi Shyti, Vivi Rodrigo, Tvrtko Ursulin,
Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, linux-kernel@vger.kernel.org,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-modules@vger.kernel.org, linux-trace-kernel@vger.kernel.org
In-Reply-To: <e171f94d-060b-448c-aab5-bafc01fea7fe@nvidia.com>
On Mon, 5 Jan 2026 14:33:35 -0500
Joel Fernandes <joelagnelf@nvidia.com> wrote:
> >>> I'm thinking that my proposed config option is the best solution now. For
> >>> those that do not care about debugging the kernel, you enable the
> >>> "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
> >>> everyone else, it will not slow down their workflow when they need to debug
> >>> code.
> >>
> >> 100% agree. We do have people running custom configs for faster builds, so this
> >> hide thing could be enabled there assuming those don't care about debug.
> >>
> >> In other words, "If it aint broke, don't fix it".
> >
> > But if I understand correctly, it would save 2% build time. That means 12
> > secondes on a 10 minutes build. Is it really worth it ?
> >
> 99% of my kernel builds are usually 90 seconds. I throw a lot of cores at it and
> with ccache. I care more about trace_printk not being available than saving 2%.
> But YMMV. I am sure there are people who care a lot about build time, but for me
> it has not (yet) been a problem.
I can see Linus enabling this. I don't think he uses trace_printk() to
debug the kernel, so improving his build times may be useful.
-- Steve
^ permalink raw reply
* Re: [PATCH v4 7/7] kernel.h: drop trace_printk.h
From: Joel Fernandes @ 2026-01-05 20:15 UTC (permalink / raw)
To: Steven Rostedt
Cc: Christophe Leroy (CS GROUP), Andy Shevchenko, Andrew Morton,
Yury Norov, Masami Hiramatsu, Mathieu Desnoyers, Randy Dunlap,
Ingo Molnar, Jani Nikula, Joonas Lahtinen, David Laight,
Petr Pavlu, Andi Shyti, Vivi Rodrigo, Tvrtko Ursulin,
Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, linux-kernel@vger.kernel.org,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-modules@vger.kernel.org, linux-trace-kernel@vger.kernel.org
In-Reply-To: <20260105150453.127927c9@gandalf.local.home>
On 1/5/2026 3:04 PM, Steven Rostedt wrote:
> On Mon, 5 Jan 2026 14:33:35 -0500
> Joel Fernandes <joelagnelf@nvidia.com> wrote:
>
>>>>> I'm thinking that my proposed config option is the best solution now. For
>>>>> those that do not care about debugging the kernel, you enable the
>>>>> "HIDE_TRACE_PRINTK" config so that your builds will be "quicker". But for
>>>>> everyone else, it will not slow down their workflow when they need to debug
>>>>> code.
>>>>
>>>> 100% agree. We do have people running custom configs for faster builds, so this
>>>> hide thing could be enabled there assuming those don't care about debug.
>>>>
>>>> In other words, "If it aint broke, don't fix it".
>>>
>>> But if I understand correctly, it would save 2% build time. That means 12
>>> secondes on a 10 minutes build. Is it really worth it ?
>>>
>> 99% of my kernel builds are usually 90 seconds. I throw a lot of cores at it and
>> with ccache. I care more about trace_printk not being available than saving 2%.
>> But YMMV. I am sure there are people who care a lot about build time, but for me
>> it has not (yet) been a problem.
>
> I can see Linus enabling this. I don't think he uses trace_printk() to
> debug the kernel, so improving his build times may be useful.
Sounds good to me. Making it an option sounds okay to me. Thanks.
^ permalink raw reply
* Re: [PATCH v11 2/8] pkcs7: Allow the signing algo to calculate the digest itself
From: Ignat Korchagin @ 2026-01-05 20:19 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, 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: <20260105152145.1801972-3-dhowells@redhat.com>
Hi David,
On Mon, Jan 5, 2026 at 3:22 PM David Howells <dhowells@redhat.com> wrote:
>
> The ML-DSA public key algorithm really wants to calculate the message
> digest itself, rather than having the digest precalculated and fed to it
> separately as RSA does[*]. The kernel's PKCS#7 parser, however, is
> designed around the latter approach.
>
> [*] ML-DSA does allow for an "external mu", but CMS doesn't yet have that
> standardised.
>
> Fix this by noting in the public_key_signature struct when the signing
> algorithm is going to want this and then, rather than doing the digest of
> the authenticatedAttributes ourselves and overwriting the sig->digest with
> that, replace sig->digest with a copy of the contents of the
> authenticatedAttributes section and adjust the digest length to match.
>
> This will then be fed to the public key algorithm as normal which can do
> what it wants with the data.
>
> 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 | 48 ++++++++++++++++++---------
> include/crypto/public_key.h | 1 +
> 3 files changed, 36 insertions(+), 17 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 6d6475e3a9bf..0f9f515b784d 100644
> --- a/crypto/asymmetric_keys/pkcs7_verify.c
> +++ b/crypto/asymmetric_keys/pkcs7_verify.c
> @@ -70,8 +70,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;
> @@ -97,20 +95,40 @@ 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->digest, 0, sig->digest_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->digest);
> - if (ret < 0)
> - goto error;
> + if (sig->algo_does_hash) {
> + kfree(sig->digest);
> +
> + ret = -ENOMEM;
> + sig->digest = kmalloc(umax(sinfo->authattrs_len, sig->digest_size),
> + GFP_KERNEL);
Can we refactor this so we allocate the right size from the start.
Alternatively, should we just unconditionally use this approach
"overallocating" some times?
> + if (!sig->digest)
> + goto error_no_desc;
> +
> + sig->digest_size = sinfo->authattrs_len;
> + memcpy(sig->digest, sinfo->authattrs, sinfo->authattrs_len);
> + ((u8 *)sig->digest)[0] = ASN1_CONS_BIT | ASN1_SET;
> + ret = 0;
> + } else {
> + u8 tag = ASN1_CONS_BIT | ASN1_SET;
> +
> + ret = crypto_shash_init(desc);
> + if (ret < 0)
> + goto error;
> + ret = crypto_shash_update(desc, &tag, 1);
> + if (ret < 0)
> + goto error;
> + ret = crypto_shash_finup(desc, sinfo->authattrs + 1,
> + sinfo->authattrs_len - 1,
> + sig->digest);
> + if (ret < 0)
> + goto error;
> + }
> pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
> }
>
> diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
> index 81098e00c08f..e4ec8003a3a4 100644
> --- a/include/crypto/public_key.h
> +++ b/include/crypto/public_key.h
> @@ -46,6 +46,7 @@ struct public_key_signature {
> u8 *digest;
> u32 s_size; /* Number of bytes in signature */
> u32 digest_size; /* Number of bytes in digest */
> + bool algo_does_hash; /* Public key algo does its own hashing */
It seems this controls if we hash authenticated attributes, not the
data itself. Maybe reflect this in the name? Something like
do_authattrs_hash or authattrs_algo_passthrough?
> const char *pkey_algo;
> const char *hash_algo;
> const char *encoding;
>
Ignat
^ permalink raw reply
* Re: [PATCH v11 3/8] pkcs7, x509: Add ML-DSA support
From: Eric Biggers @ 2026-01-06 8:02 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, Ignat Korchagin, Jarkko Sakkinen, Herbert Xu,
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: <20260105152145.1801972-4-dhowells@redhat.com>
On Mon, Jan 05, 2026 at 03:21:28PM +0000, David Howells wrote:
> Add support for ML-DSA keys and signatures to the PKCS#7 and X.509
> implementations.
>
> 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 | 15 ++++++++++++++
> crypto/asymmetric_keys/public_key.c | 7 +++++++
> crypto/asymmetric_keys/x509_cert_parser.c | 24 +++++++++++++++++++++++
> include/linux/oid_registry.h | 5 +++++
> 4 files changed, 51 insertions(+)
This "PKCS#7" (really CMS -- the kernel misleadingly uses the old name)
stuff is really hard to understand. I'm trying to understand what
message you're actually passing to mldsa_verify(). That's kind of the
whole point, after all.
The message comes from the byte array public_key_signature::digest
(which is misleadingly named, as it's not always a digest). In turn,
that comes from the following:
1.) If the CMS object doesn't include signed attributes, then it's a
digest of the real message the caller provided.
2.) If the CMS object includes signed attributes, then the message is
the signed attributes as a byte array. The signed attributes are
required to include a message digest attribute whose value matches a
digest of the real message the caller provided.
In either (1) or (2), the digest algorithm used comes from the CMS
object itself, from SignerInfo::digestAlgorithm. The kernel allows
SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SM3, Streebog-256,
Streebog-512, SHA3-256, SHA3-384, and SHA3-512.
So, a couple issues. First, case (1) isn't actually compatible with
RFC 9882 (https://datatracker.ietf.org/doc/rfc9882/) which is the
specification for ML-DSA support in CMS. RFC 9882 is clear that if
there are no signed attributes, then the ML-DSA signature is computed
directly over the signed-data, not over a digest of it.
That needs to either be implemented correctly, or not at all. (If only
(2) is actually needed, then "not at all" probably would be preferable.)
Second, because the digest algorithm comes from the untrusted signature
object and the kernel is allowing different many digest algorithms,
attackers are free to search for preimages across algorithms. For
example, if an attacker can find a Streebog-512 digest that matches a
particular SHA-512 digest that was used in a valid signature, they could
forge signatures. This would only require a weakness in Streebog-512.
While the root cause of this seems to be a flaw in CMS itself, it can be
mitigated by more strictly limiting the allowed digest algorithms. The
kernel already does this for the existing signature algorithms.
For simplicity and to avoid this issue entirely, I suggest just allowing
SHA-512 only. That's the only one that RFC 9882 says MUST be supported
with ML-DSA.
- Eric
^ permalink raw reply
* Re: [PATCH v11 4/8] modsign: Enable ML-DSA module signing
From: Eric Biggers @ 2026-01-06 8:10 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, Ignat Korchagin, Jarkko Sakkinen, Herbert Xu,
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: <20260105152145.1801972-5-dhowells@redhat.com>
On Mon, Jan 05, 2026 at 03:21:29PM +0000, David Howells wrote:
> The ML-DSA algorithm uses its own internal choice of digest (SHAKE256)
> without regard to what's specified in the CMS message. This is, in theory,
> configurable, but there's currently no hook in the crypto_sig API to do
> that, though possibly it could be done by parameterising the name of the
> algorithm, e.g. ("mldsa87(sha512)").
The ML-DSA specification specifies the XOFs used. This has nothing to
do with the API.
> +config MODULE_SIG_KEY_TYPE_MLDSA_44
> + bool "ML-DSA (Dilithium) 44"
> + select CRYPTO_MLDSA
> + help
> + Use an ML-DSA (Dilithium) 44 key (NIST FIPS 204) for module signing
> + with a SHAKE256 'hash' of the authenticatedAttributes.
> +
> +config MODULE_SIG_KEY_TYPE_MLDSA_65
> + bool "ML-DSA (Dilithium) 65"
> + select CRYPTO_MLDSA
> + help
> + Use an ML-DSA (Dilithium) 65 key (NIST FIPS 204) for module signing
> + with a SHAKE256 'hash' of the authenticatedAttributes.
> +
> +config MODULE_SIG_KEY_TYPE_MLDSA_87
> + bool "ML-DSA (Dilithium) 87"
> + select CRYPTO_MLDSA
> + help
> + Use an ML-DSA (Dilithium) 87 key (NIST FIPS 204) for module signing
> + with a SHAKE256 'hash' of the authenticatedAttributes.
Kind of weird naming here. We don't have "AES (Rijndael) 256" and
"SHA-3 (Keccak) 512". We have AES-256 and SHA3-256.
Similarly, these should be ML-DSA-44, etc.
Yes, NIST went with boring names instead of the original cool names.
That's just how it is.
Also unclear why the above help text mentions anything about SHAKE256 or
the authenticatedAttributes. That's an implementation detail. (And the
CMS specification calls them signed attributes anyway.)
- Eric
^ permalink raw reply
* Re: [PATCH v11 3/8] pkcs7, x509: Add ML-DSA support
From: Eric Biggers @ 2026-01-06 8:22 UTC (permalink / raw)
To: David Howells
Cc: Lukas Wunner, Ignat Korchagin, Jarkko Sakkinen, Herbert Xu,
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: <20260106080251.GD2630@sol>
On Tue, Jan 06, 2026 at 12:02:51AM -0800, Eric Biggers wrote:
> For simplicity and to avoid this issue entirely, I suggest just allowing
> SHA-512 only. That's the only one that RFC 9882 says MUST be supported
> with ML-DSA.
That being said, this is only applicable for the case where signed
attributes are used. If you can get the other case working properly and
just support that case, where the real user message is what is passed to
ML-DSA, that would also avoid this issue and be much simpler.
- Eric
^ permalink raw reply
* Re: [PATCH v11 3/8] pkcs7, x509: Add ML-DSA support
From: David Howells @ 2026-01-06 9:37 UTC (permalink / raw)
To: Eric Biggers
Cc: dhowells, Lukas Wunner, Ignat Korchagin, Jarkko Sakkinen,
Herbert Xu, 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: <20260106080251.GD2630@sol>
Eric Biggers <ebiggers@kernel.org> wrote:
> This "PKCS#7" (really CMS -- the kernel misleadingly uses the old name)
I implemented PKCS#7 first and then added CMS on top of that.
> That needs to either be implemented correctly, or not at all. (If only
> (2) is actually needed, then "not at all" probably would be preferable.)
At the time of writing, openssl didn't fully support CMS with ML-DSA, and that
limited things.
David
^ permalink raw reply
* Re: [PATCH] software node: replace -EEXIST with -EBUSY
From: Lucas De Marchi @ 2026-01-06 14:24 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Daniel Gomez, Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Rafael J. Wysocki, Danilo Krummrich,
Luis Chamberlain, Petr Pavlu, Sami Tolvanen, Aaron Tomlin,
linux-acpi, linux-modules, linux-kernel, Daniel Gomez
In-Reply-To: <2025122212-fiction-setback-ede5@gregkh>
On Mon, Dec 22, 2025 at 12:56:38PM +0100, Greg Kroah-Hartman wrote:
>On Mon, Dec 22, 2025 at 09:48:54AM +0100, Daniel Gomez wrote:
>> On 22/12/2025 09.19, Greg Kroah-Hartman wrote:
>> > On Sat, Dec 20, 2025 at 04:55:00AM +0100, Daniel Gomez wrote:
>> >> From: Daniel Gomez <da.gomez@samsung.com>
>> >>
>> >> The -EEXIST error code is reserved by the module loading infrastructure
>> >> to indicate that a module is already loaded. When a module's init
>> >> function returns -EEXIST, userspace tools like kmod interpret this as
>> >> "module already loaded" and treat the operation as successful, returning
>> >> 0 to the user even though the module initialization actually failed.
>> >>
>> >> This follows the precedent set by commit 54416fd76770 ("netfilter:
>> >> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
>> >> issue in nf_conntrack_helper_register().
>> >>
>> >> Affected modules:
>> >> * meraki_mx100 pcengines_apuv2
>> >>
>> >> Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
>> >> ---
>> >> The error code -EEXIST is reserved by the kernel module loader to
>> >> indicate that a module with the same name is already loaded. When a
>> >> module's init function returns -EEXIST, kmod interprets this as "module
>> >> already loaded" and reports success instead of failure [1].
>> >>
>> >> The kernel module loader will include a safety net that provides -EEXIST
>> >> to -EBUSY with a warning [2], and a documentation patch has been sent to
>> >> prevent future occurrences [3].
>> >>
>> >> These affected code paths were identified using a static analysis tool
>> >> [4] that traces -EEXIST returns to module_init(). The tool was developed
>> >> with AI assistance and all findings were manually validated.
>> >>
>> >> Link: https://lore.kernel.org/all/aKEVQhJpRdiZSliu@orbyte.nwl.cc/ [1]
>> >> Link: https://lore.kernel.org/all/20251013-module-warn-ret-v1-0-ab65b41af01f@intel.com/ [2]
>> >> Link: https://lore.kernel.org/all/20251218-dev-module-init-eexists-modules-docs-v1-0-361569aa782a@samsung.com/ [3]
>> >> Link: https://gitlab.com/-/snippets/4913469 [4]
>> >> ---
>> >> drivers/base/swnode.c | 2 +-
>> >> 1 file changed, 1 insertion(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
>> >> index 16a8301c25d6..083593d99a18 100644
>> >> --- a/drivers/base/swnode.c
>> >> +++ b/drivers/base/swnode.c
>> >> @@ -919,7 +919,7 @@ int software_node_register(const struct software_node *node)
>> >> struct swnode *parent = software_node_to_swnode(node->parent);
>> >>
>> >> if (software_node_to_swnode(node))
>> >> - return -EEXIST;
>> >> + return -EBUSY;
>> >
>> > While I understand the want for the module loader to be returning
>> > -EBUSY, that doesn't really make sense down here in this layer of the
>> > kernel.
>> >
>> > So why doesn't the module loader turn -EEXIST return values into -EBUSY
>> > if it wishes to pass that value on to userspace? Otherwise you are
>>
>> Indeed, we are planning to do that as well with "[PATCH 0/2] module: Tweak
>> return and warning":
>>
>> https://lore.kernel.org/all/20251013-module-warn-ret-v1-0-ab65b41af01f@intel.com/#t
>>
>> However, we don't consider that as the right fix.
>>
>> > going to be constantly playing "whack-a-mole" here and have really
>> > set things up so that NO api can ever return EEXIST as an error value in
>> > the future.
>>
>> 100%.
>>
>> For that reason, on top of the series from Lucas, we are documenting this to
>> make it clear:
>>
>> https://lore.kernel.org/linux-modules/20251218-dev-module-init-eexists-modules-docs-v1-0-361569aa782a@samsung.com/T/#m2ed6fbffb3f78b9bff53840f6492a198c389cb50
>
>Wait, no, that's not what I mean at all :)
>
>> And sending patches where we see modules need fixing. I have already sent 6 out
>> of 20-ish series (that include a total of 40+ fixes):
>>
>> https://lore.kernel.org/all/20251220-dev-module-init-eexists-linux-scsi-v1-0-5379db749d54@samsung.com
>> https://lore.kernel.org/all/20251219-dev-module-init-eexists-netfilter-v1-1-efd3f62412dc@samsung.com
>> https://lore.kernel.org/all/20251220-dev-module-init-eexists-bpf-v1-1-7f186663dbe7@samsung.com
>> https://lore.kernel.org/all/20251220-dev-module-init-eexists-keyring-v1-1-a2f23248c300@samsung.com
>> https://lore.kernel.org/all/20251220-dev-module-init-eexists-dm-devel-v1-1-90ed00444ea0@samsung.com
>
>Please no, let us keep using -EEXIST in the kernel source, and if your
>usage is going to map this to userspace somehow, do the translation
>there, in the module code, as your original patch above said.
>
>Otherwise, again, this is never going to work, let the subsystems use
>this error code how ever they feel they need to.
Ok. When I added the warning I was more following what the other error
handling was doing for positive values. Happy to change that to simply
map the error code before returning from do_init_module().
Daniel, do you want me to resend that with the warning removed?
Lucas De Marchi
>
>thanks,
>
>greg k-h
^ permalink raw reply
* Re: [PATCH] KEYS: replace -EEXIST with -EBUSY
From: Lucas De Marchi @ 2026-01-06 15:04 UTC (permalink / raw)
To: David Howells
Cc: Daniel Gomez, Lukas Wunner, Ignat Korchagin, Herbert Xu,
David S. Miller, Jarkko Sakkinen, Paul Moore, James Morris,
Serge E. Hallyn, Luis Chamberlain, Petr Pavlu, Sami Tolvanen,
Aaron Tomlin, keyrings, linux-crypto, linux-modules, linux-kernel,
linux-security-module, Daniel Gomez, Greg Kroah-Hartman
In-Reply-To: <1793804.1767607035@warthog.procyon.org.uk>
+Greg, to consolidate from the othe thread.
On Mon, Jan 05, 2026 at 09:57:15AM +0000, David Howells wrote:
>Daniel Gomez <da.gomez@kernel.org> wrote:
>
>> From: Daniel Gomez <da.gomez@samsung.com>
>>
>> The -EEXIST error code is reserved by the module loading infrastructure
>> to indicate that a module is already loaded.
>
>EEXIST means a file exists when you're trying to create it. Granted we abuse
>that somewhat rather than add ever more error codes, but you cannot reserve it
>for indicating that a module exists.
EEXIST from [f]init_module() means "module is already loaded" and it
can't mean something else for this syscall. Other return codes are
explained in the man page, but aren't that special from the userspace
pov.
This doesn't mean we need to replace all the EBUSY throughout the call
chain with EEXIST, but the return from the syscall needs to remain
consistent if that was the case for it failing. Ideally that mapping
would come from the module init (and not from other functions it calls)
because that is the place that has that knowledge.
If a generic EBUSY->EEXIST mapping is desired, as it seems to be the
case from
https://lore.kernel.org/all/2025122212-fiction-setback-ede5@gregkh/,
then do_init_module() can do it, but in practice that means reserving 2
error codes rather than 1.
>
>> When a module's init
>> function returns -EEXIST, userspace tools like kmod interpret this as
>> "module already loaded" and treat the operation as successful, returning
>> 0 to the user even though the module initialization actually failed.
>>
>> This follows the precedent set by commit 54416fd76770 ("netfilter:
>> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
>> issue in nf_conntrack_helper_register().
>>
>> Affected modules:
>> * pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
>> * nvme_keyring pkcs7_test_key rxrpc turris_signing_key
>>
>> Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
>
>Please don't. Userspace can always check /proc/modules (assuming procfs is
>enabled, I suppose).
EEXIST is already there with that meaning. Checking procfs (or sysfs as
kmod currently does) is racy and doesn't look like a good API - why
would userspace have to check if the module is loaded when the syscall
that loads the module failed? EEXIST is special exactly to resolve races
with 2 threads trying to load the same module.
Lucas De Marchi
>
>David
>
^ permalink raw reply
* [PATCH RFC v2 00/11] rust: Reimplement ThisModule to fix ownership problems
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Alexandre Courbot
Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Kari Argillander, Youseok Yang, Yuheng Su
Still RFC. Not all people for each subsystems are not included yet as
this touch quite lot of things. Introducing new THIS_MODULE and
ThisModule still change configfs in same patch which is not ideal.
So currently we have problem that we are not always filling .owner field
for file_operations. I think we can enable const_refs_to_static already
as that is in 1.78 and is stable in 1.83. So that fits perfecly for us.
This also seems to be quite request feature but I did not found that no
one has ever suggested that we just enable this.
So basic idea is that we will have ThisModule trait which is used kernel
side. Module side we will always use THIS_MODULE. That is completly
private for modules and kernel cannot use it. So this unifies ways of
using cofing ThisModule things. Currently we have THIS_MODULE and also
module: &' static ThisModule
on init functions. As we anyway need THIS_MODULE just use that.
Argillander
To: Miguel Ojeda <ojeda@kernel.org>
To: Boqun Feng <boqun.feng@gmail.com>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <lossin@kernel.org>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
To: Danilo Krummrich <dakr@kernel.org>
To: Alexandre Courbot <acourbot@nvidia.com>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Petr Pavlu <petr.pavlu@suse.com>
Cc: Daniel Gomez <da.gomez@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
Changes in v2:
- Patches are now sepereted properly.
- Removed debugfs changes as that is not so clear to me.
- Remove module parameter and just used THIS_MODULE everywhere.
- Made macro to make THIS_MODULE.
- Doc tests also have THIS_MODULE.
- Link to v1: https://lore.kernel.org/r/20260101-this_module_fix-v1-0-46ae3e5605a0@gmail.com
---
Kari Argillander (11):
rust: enable const_refs_to_static feature
rust: add new ThisModule trait and THIS_MODULE impl
rust: miscdevice: fix use after free because missing .owner
rust: block: fix missing owner field in block_device_operations
rust: drm: fix missing owner in file_operations
rust: driver: make RegistrationOps::register() to use new ThisModule
rust: phy: make Registration::register() use new ThisModule
rust: binder: use new THIS_MODULE
rust: remove module argument from InPlaceModule::init()
rust: remove kernel::ModuleMetadata
rust: remove old version of ThisModule
drivers/android/binder/rust_binder_main.rs | 5 +-
drivers/block/rnull/configfs.rs | 2 +-
drivers/block/rnull/rnull.rs | 3 +-
drivers/gpu/drm/nova/driver.rs | 2 +
drivers/gpu/drm/tyr/driver.rs | 2 +
drivers/gpu/nova-core/nova_core.rs | 2 +-
lib/find_bit_benchmark_rust.rs | 3 +-
rust/kernel/auxiliary.rs | 16 +--
rust/kernel/block/mq.rs | 1 +
rust/kernel/block/mq/gen_disk.rs | 30 +-----
rust/kernel/block/mq/operations.rs | 30 ++++++
rust/kernel/configfs.rs | 49 ++++-----
rust/kernel/driver.rs | 31 +++---
rust/kernel/drm/device.rs | 2 +-
rust/kernel/drm/driver.rs | 4 +
rust/kernel/drm/gem/mod.rs | 5 +-
rust/kernel/firmware.rs | 4 +-
rust/kernel/i2c.rs | 11 +-
rust/kernel/lib.rs | 161 ++++++++++++++++++++++++-----
rust/kernel/miscdevice.rs | 5 +
rust/kernel/net/phy.rs | 29 ++++--
rust/kernel/pci.rs | 15 +--
rust/kernel/platform.rs | 12 +--
rust/kernel/prelude.rs | 2 +-
rust/kernel/sync/lock/global.rs | 4 +-
rust/kernel/usb.rs | 13 +--
rust/macros/lib.rs | 4 +-
rust/macros/module.rs | 24 +----
samples/rust/rust_configfs.rs | 2 +-
samples/rust/rust_debugfs_scoped.rs | 2 +-
samples/rust/rust_driver_auxiliary.rs | 8 +-
samples/rust/rust_driver_faux.rs | 2 +-
samples/rust/rust_minimal.rs | 2 +-
samples/rust/rust_misc_device.rs | 3 +-
samples/rust/rust_print_main.rs | 2 +-
scripts/rustdoc_test_gen.rs | 2 +
36 files changed, 298 insertions(+), 196 deletions(-)
---
base-commit: 6cd6c12031130a349a098dbeb19d8c3070d2dfbe
change-id: 20251230-this_module_fix-a390bff24897
Best regards,
--
Kari Argillander <kari.argillander@gmail.com>
^ permalink raw reply
* [PATCH RFC v2 01/11] rust: enable const_refs_to_static feature
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Alexandre Courbot
Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Kari Argillander
In-Reply-To: <20260106-this_module_fix-v2-0-842ac026f00b@gmail.com>
Enable the const_refs_to_static Rust feature to allow taking
references to static items in const contexts. This is required for
using ThisModule when constructing static Rust structures.
The Rust support already relies on features available in Rust 1.83, and
const_refs_to_static has been available since Rust 1.78.
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
rust/kernel/lib.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 6d637e2fed1b..510d4bfc7c2b 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -36,6 +36,7 @@
#![feature(const_option)]
#![feature(const_ptr_write)]
#![feature(const_refs_to_cell)]
+#![feature(const_refs_to_static)]
//
// Expected to become stable.
#![feature(arbitrary_self_types)]
--
2.43.0
^ permalink raw reply related
* [PATCH RFC v2 02/11] rust: add new ThisModule trait and THIS_MODULE impl
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Alexandre Courbot
Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Kari Argillander
In-Reply-To: <20260106-this_module_fix-v2-0-842ac026f00b@gmail.com>
To make clear separation between module crates and kernel crate we
introduce ThisModule trait which is meant to be used by kernel space.
THIS_MODULE is meant to be used by modules. So kernel create will be
unable to even accidentally use THIS_MODULE.
As ThisModule is trait we can pass that around in const context. This is
needed so that we can read ownership information in const context when
we create example file_operations structs for modules.
New ThisModule will also eventually replace kernel::ModuleMetadata trait
and for this reason it also have NAME field.
To make transition smooth use mod this_module so we can have two
ThisModule same time. Also some functionality is added to THIS_MODULE
temporarily so that we do not have to change everything at once.
Also examples will need THIS_MODULE so also define that in docs.
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
drivers/block/rnull/configfs.rs | 2 +-
rust/kernel/configfs.rs | 46 ++++++------
rust/kernel/lib.rs | 159 ++++++++++++++++++++++++++++++++++++++++
rust/macros/module.rs | 16 +---
scripts/rustdoc_test_gen.rs | 2 +
5 files changed, 188 insertions(+), 37 deletions(-)
diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
index 2f5a7da03af5..7223ee7c3032 100644
--- a/drivers/block/rnull/configfs.rs
+++ b/drivers/block/rnull/configfs.rs
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
-use super::{NullBlkDevice, THIS_MODULE};
+use super::NullBlkDevice;
use kernel::{
block::mq::gen_disk::{GenDisk, GenDiskBuilder},
c_str,
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index 466fb7f40762..908cb98d404f 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -110,16 +110,21 @@
//! [C documentation]: srctree/Documentation/filesystems/configfs.rst
//! [`rust_configfs.rs`]: srctree/samples/rust/rust_configfs.rs
-use crate::alloc::flags;
-use crate::container_of;
-use crate::page::PAGE_SIZE;
-use crate::prelude::*;
-use crate::str::CString;
-use crate::sync::Arc;
-use crate::sync::ArcBorrow;
-use crate::types::Opaque;
-use core::cell::UnsafeCell;
-use core::marker::PhantomData;
+use crate::{
+ alloc::flags,
+ container_of,
+ page::PAGE_SIZE,
+ prelude::*,
+ str::CString,
+ sync::Arc,
+ sync::ArcBorrow,
+ this_module::ThisModule,
+ types::Opaque, //
+};
+use core::{
+ cell::UnsafeCell,
+ marker::PhantomData, //
+};
/// A configfs subsystem.
///
@@ -744,8 +749,7 @@ macro_rules! impl_item_type {
($tpe:ty) => {
impl<Data> ItemType<$tpe, Data> {
#[doc(hidden)]
- pub const fn new_with_child_ctor<const N: usize, Child>(
- owner: &'static ThisModule,
+ pub const fn new_with_child_ctor<const N: usize, Child, TM: ThisModule>(
attributes: &'static AttributeList<N, Data>,
) -> Self
where
@@ -754,7 +758,7 @@ pub const fn new_with_child_ctor<const N: usize, Child>(
{
Self {
item_type: Opaque::new(bindings::config_item_type {
- ct_owner: owner.as_ptr(),
+ ct_owner: TM::OWNER.as_ptr(),
ct_group_ops: GroupOperationsVTable::<Data, Child>::vtable_ptr().cast_mut(),
ct_item_ops: ItemOperationsVTable::<$tpe, Data>::vtable_ptr().cast_mut(),
ct_attrs: core::ptr::from_ref(attributes).cast_mut().cast(),
@@ -765,13 +769,12 @@ pub const fn new_with_child_ctor<const N: usize, Child>(
}
#[doc(hidden)]
- pub const fn new<const N: usize>(
- owner: &'static ThisModule,
+ pub const fn new<const N: usize, TM: ThisModule>(
attributes: &'static AttributeList<N, Data>,
) -> Self {
Self {
item_type: Opaque::new(bindings::config_item_type {
- ct_owner: owner.as_ptr(),
+ ct_owner: TM::OWNER.as_ptr(),
ct_group_ops: core::ptr::null_mut(),
ct_item_ops: ItemOperationsVTable::<$tpe, Data>::vtable_ptr().cast_mut(),
ct_attrs: core::ptr::from_ref(attributes).cast_mut().cast(),
@@ -875,8 +878,7 @@ fn as_ptr(&self) -> *const bindings::config_item_type {
/// = kernel::configfs::ItemType::<
/// configfs::Subsystem<Configuration>,
/// Configuration
-/// >::new_with_child_ctor::<N,Child>(
-/// &THIS_MODULE,
+/// >::new_with_child_ctor::<N, Child, crate::THIS_MODULE>(
/// &CONFIGURATION_ATTRS
/// );
///
@@ -1019,8 +1021,8 @@ macro_rules! configfs_attrs {
const [<$no_child:upper>]: bool = true;
static [< $data:upper _TPE >] : $crate::configfs::ItemType<$container, $data> =
- $crate::configfs::ItemType::<$container, $data>::new::<N>(
- &THIS_MODULE, &[<$ data:upper _ATTRS >]
+ $crate::configfs::ItemType::<$container, $data>::new::<N, crate::THIS_MODULE>(
+ &[<$ data:upper _ATTRS >]
);
)?
@@ -1028,8 +1030,8 @@ macro_rules! configfs_attrs {
static [< $data:upper _TPE >]:
$crate::configfs::ItemType<$container, $data> =
$crate::configfs::ItemType::<$container, $data>::
- new_with_child_ctor::<N, $child>(
- &THIS_MODULE, &[<$ data:upper _ATTRS >]
+ new_with_child_ctor::<N, $child, crate::THIS_MODULE>(
+ &[<$ data:upper _ATTRS >]
);
)?
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 510d4bfc7c2b..2ccd75f68f03 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -233,6 +233,165 @@ pub const fn as_ptr(&self) -> *mut bindings::module {
}
}
+pub mod this_module {
+ //! Access to the module identity and ownership information.
+ //!
+ //! This module provides the Rust equivalent of the kernel’s `THIS_MODULE`
+ //! symbol from the [C API](srctree/include/linux/init.h).
+ //!
+ //! # For driver creators
+ //!
+ //! If you see ThisModule you need to pass THIS_NODULE for it so it can
+ //! track module ownership.
+ //!
+ //! Each Rust module defines its own `THIS_MODULE` using the
+ //! [`create_this_module`] macro. The generated `THIS_MODULE` identifies the
+ //! owning kernel module and expose some metadata about it.
+ //!
+ //! # For abstraction creators
+ //!
+ //! Many times C-apis expect a `struct module *` pointer so they can
+ //! increase the module reference count. This is because module could be
+ //! unloaded while example file operations are in progress. Many times
+ //! structs which needs owner fields should also be const. For this reason
+ //! ThisModule is usually passes as a type parameter `TM` to abstractions
+ //! which need to know the module owner. In vtables ThisModule is usually
+ //! used as name.
+ //!
+ //! ## Example
+ //!
+ //! ```
+ //! # use kernel::{bindings, this_module::ThisModule};
+ //! # use core::marker::PhantomData;
+ //!
+ //! // Example function signature which needs ThisModule.
+ //! pub fn create_device<TM: ThisModule>() {}
+ //!
+ //! // Example of a vtable which uses ThisModule.
+ //! #[vtable]
+ //! pub trait MyStruct {
+ //! type ThisModule: ThisModule;
+ //! }
+ //!
+ //! pub(crate) struct MyStructVTable<T: MyStruct>(PhantomData<T>);
+ //!
+ //! impl<T: MyStruct> MyStructVTable<T> {
+ //! const FOPS: bindings::file_operations = bindings::file_operations {
+ //! owner: T::ThisModule::OWNER.as_ptr(),
+ //! ..pin_init::zeroed()
+ //! };
+ //! }
+ //! ```
+
+ /// See [`this_module`]
+ pub trait ThisModule {
+ /// Wrapper around the owning `struct module` pointer.
+ ///
+ /// This is null for built-in code and non-null for loadable modules.
+ const OWNER: ModuleWrapper;
+ /// Name of the module.
+ const NAME: &'static kernel::str::CStr;
+ }
+
+ /// Wrapper around a pointer to `struct module`.
+ ///
+ /// This type exists as a workaround for the lack of `const fn` methods in
+ /// traits. It allows the module pointer to be stored as an associated
+ /// constant while still providing a `const` accessor.
+ pub struct ModuleWrapper {
+ ptr: *mut bindings::module,
+ }
+
+ impl ModuleWrapper {
+ /// Get the raw pointer to the underlying `struct module`.
+ ///
+ /// TODO: Should be only available for kernel create.
+ pub const fn as_ptr(&self) -> *mut bindings::module {
+ self.ptr
+ }
+
+ /// Only meant to be used from [`create_this_module`].
+ ///
+ /// # Safety
+ ///
+ /// - Only modules are allowed to create non null `ModuleWrapper`s.
+ /// - The non null pointer must point to a valid `struct module`
+ /// provided by the kernel.
+ #[doc(hidden)]
+ pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> Self {
+ ModuleWrapper { ptr }
+ }
+ }
+
+ /// Creates the `THIS_MODULE` definition for a Rust module.
+ ///
+ /// This macro is an internal building block and is not intended to be used
+ /// directly by module authors. It is invoked by [`macros::module::module`]
+ /// and by kernel doctests.
+ ///
+ /// A macro is required so that `cfg(MODULE)` is evaluated in the context of
+ /// the consuming crate, and to prevent accidental use of THIS_MODULE from
+ /// within the kernel crate itself.
+ #[macro_export]
+ #[doc(hidden)]
+ macro_rules! create_this_module {
+ ($name:literal) => {
+ /// THIS_MODULE for module `{name}`. See [`kernel::this_module`].
+ #[allow(non_camel_case_types)]
+ pub struct THIS_MODULE;
+
+ impl ::kernel::this_module::ThisModule for THIS_MODULE {
+ #[cfg(not(MODULE))]
+ /// SAFETY: TODO
+ const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {
+ ::kernel::this_module::ModuleWrapper::from_ptr(::core::ptr::null_mut())
+ };
+
+ #[cfg(MODULE)]
+ // SAFETY:
+ // - `__this_module` is constructed by the kernel at module load time.
+ const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {
+ extern "C" {
+ static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
+ }
+
+ ::kernel::this_module::ModuleWrapper::from_ptr(__this_module.get())
+ };
+
+ const NAME: &'static ::kernel::str::CStr = $crate::c_str!($name);
+ }
+
+ impl THIS_MODULE {
+ /// Returns the name of this module.
+ pub const fn name() -> &'static ::kernel::str::CStr {
+ $crate::c_str!($name)
+ }
+
+ // TODO: Temporary to provide functionality old `THIS_MODULE` provided.
+ // SAFETY: `__this_module` is constructed by the kernel at load time and
+ // will not be freed until the module is unloaded.
+ const ThisModule: ::kernel::ThisModule = unsafe {{
+ ::kernel::ThisModule::from_ptr(
+ <Self as ::kernel::this_module::ThisModule>::OWNER.as_ptr()
+ )
+ }};
+
+ /// Gets a pointer to the underlying `struct module`.
+ // TODO: Temporary to provide functionality old `THIS_MODULE` provided.
+ pub const fn as_ptr(&self) -> *mut ::kernel::bindings::module {{
+ Self::ThisModule.as_ptr()
+ }}
+
+ /// Gets a reference to the underlying `ThisModule`.
+ /// TODO: Temporary to provide functionality old `THIS_MODULE` provided.
+ pub const fn as_ref(&self) -> &'static ::kernel::ThisModule {{
+ &Self::ThisModule
+ }}
+ }
+ };
+ }
+}
+
#[cfg(not(testlib))]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 80cb9b16f5aa..1bcd703735fe 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -371,20 +371,8 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
/// Used by the printing macros, e.g. [`info!`].
const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
- // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
- // freed until the module is unloaded.
- #[cfg(MODULE)]
- static THIS_MODULE: ::kernel::ThisModule = unsafe {{
- extern \"C\" {{
- static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
- }}
+ ::kernel::create_this_module!(\"{name}\");
- ::kernel::ThisModule::from_ptr(__this_module.get())
- }};
- #[cfg(not(MODULE))]
- static THIS_MODULE: ::kernel::ThisModule = unsafe {{
- ::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
- }};
/// The `LocalModule` type is the type of the module created by `module!`,
/// `module_pci_driver!`, `module_platform_driver!`, etc.
@@ -502,7 +490,7 @@ mod __module_init {{
/// This function must only be called once.
unsafe fn __init() -> ::kernel::ffi::c_int {{
let initer =
- <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE);
+ <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE.as_ref());
// SAFETY: No data race, since `__MOD` can only be accessed by this module
// and there only `__init` and `__exit` access it. These functions are only
// called once and `__exit` cannot be called before or during `__init`.
diff --git a/scripts/rustdoc_test_gen.rs b/scripts/rustdoc_test_gen.rs
index 6fd9f5c84e2e..089e38b49cdd 100644
--- a/scripts/rustdoc_test_gen.rs
+++ b/scripts/rustdoc_test_gen.rs
@@ -232,6 +232,8 @@ macro_rules! assert_eq {{
const __LOG_PREFIX: &[u8] = b"rust_doctests_kernel\0";
+::kernel::create_this_module!("rust_doctests_kernel");
+
{rust_tests}
"#
)
--
2.43.0
^ permalink raw reply related
* [PATCH RFC v2 03/11] rust: miscdevice: fix use after free because missing .owner
From: Kari Argillander @ 2026-01-06 16:11 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Alexandre Courbot
Cc: Greg Kroah-Hartman, rust-for-linux, linux-kernel, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Kari Argillander, Youseok Yang
In-Reply-To: <20260106-this_module_fix-v2-0-842ac026f00b@gmail.com>
Currently if miscdevice driver is compiled as module it can cause use
after free when unloading. To reproduce problem with Rust sample driver
we can do:
tail -f /dev/rust-misc-device
# And same time as device is open
sudo rmmod rust_misc_device_module
This will crash system. Fix is to have .owner field filled with module
information. We pass this owner information through vtable.
Reported-by: Youseok Yang <ileixe@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1182
Fixes: f893691e7426 ("rust: miscdevice: add base miscdevice abstraction")
Signed-off-by: Kari Argillander <kari.argillander@gmail.com>
---
rust/kernel/miscdevice.rs | 5 +++++
samples/rust/rust_misc_device.rs | 1 +
2 files changed, 6 insertions(+)
diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
index ba64c8a858f0..d4b0c35c4b60 100644
--- a/rust/kernel/miscdevice.rs
+++ b/rust/kernel/miscdevice.rs
@@ -18,6 +18,7 @@
mm::virt::VmaNew,
prelude::*,
seq_file::SeqFile,
+ this_module::ThisModule,
types::{ForeignOwnable, Opaque},
};
use core::{marker::PhantomData, pin::Pin};
@@ -112,6 +113,9 @@ fn drop(self: Pin<&mut Self>) {
/// Trait implemented by the private data of an open misc device.
#[vtable]
pub trait MiscDevice: Sized {
+ /// Module ownership for this device, provided via `THIS_MODULE`.
+ type ThisModule: ThisModule;
+
/// What kind of pointer should `Self` be wrapped in.
type Ptr: ForeignOwnable + Send + Sync;
@@ -388,6 +392,7 @@ impl<T: MiscDevice> MiscdeviceVTable<T> {
}
const VTABLE: bindings::file_operations = bindings::file_operations {
+ owner: T::ThisModule::OWNER.as_ptr(),
open: Some(Self::open),
release: Some(Self::release),
mmap: if T::HAS_MMAP { Some(Self::mmap) } else { None },
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 49dd5814e1ab..464e3026e6e3 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -155,6 +155,7 @@ struct RustMiscDevice {
#[vtable]
impl MiscDevice for RustMiscDevice {
+ type ThisModule = THIS_MODULE;
type Ptr = Pin<KBox<Self>>;
fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Self>>> {
--
2.43.0
^ permalink raw reply related
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