* [PATCH v4 05/10] lsm: security: Add additional enum values for bpf integrity checks
From: Blaise Boscaccy @ 2026-04-16 17:33 UTC (permalink / raw)
To: Blaise Boscaccy, Jonathan Corbet, Paul Moore, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260416173500.176716-1-bboscaccy@linux.microsoft.com>
First add a generic LSM_INT_VERDICT_FAULT value to indicate a system
failure during checking. Second, add a LSM_INT_VERDICT_UNKNOWNKEY to
signal that the payload was signed with a key other than one that
exists in the secondary keyring. And finally add an
LSM_INT_VERDICT_UNEXPECTED enum value to indicate that a unexpected
hash value was encountered at some stage of verification.
Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
---
include/linux/security.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/security.h b/include/linux/security.h
index b3fd04baa78d0..4b4b8808f67de 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -106,6 +106,9 @@ enum lsm_integrity_verdict {
LSM_INT_VERDICT_OK,
LSM_INT_VERDICT_UNSIGNED,
LSM_INT_VERDICT_PARTIALSIG,
+ LSM_INT_VERDICT_UNKNOWNKEY,
+ LSM_INT_VERDICT_UNEXPECTED,
+ LSM_INT_VERDICT_FAULT,
LSM_INT_VERDICT_BADSIG,
};
--
2.53.0
^ permalink raw reply related
* [PATCH v4 04/10] lsm: framework for BPF integrity verification
From: Blaise Boscaccy @ 2026-04-16 17:33 UTC (permalink / raw)
To: Blaise Boscaccy, Jonathan Corbet, Paul Moore, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260416173500.176716-1-bboscaccy@linux.microsoft.com>
From: Paul Moore <paul@paul-moore.com>
Add a new LSM hook and two new LSM hook callbacks to support LSMs that
perform integrity verification, e.g. digital signature verification,
of BPF programs.
While the BPF subsystem does implement a signature verification scheme,
it does not satisfy a number of existing requirements, adding support
for BPF program integrity verification to the LSM framework allows
administrators to select additional integrity verification mechanisms
to meet these needs while also providing a mechanism for future
expansion. Additional on why this is necessary can be found at the
lore archive link below:
https://lore.kernel.org/linux-security-module/CAHC9VhTQ_DR=ANzoDBjcCtrimV7XcCZVUsANPt=TjcvM4d-vjg@mail.gmail.com/
The LSM-based BPF integrity verification mechanism works within the
existing security_bpf_prog_load() hook called by the BPF subsystem.
It adds an additional dedicated integrity callback and a new LSM
hook/callback to be called from within LSMs implementing integrity
verification.
The first new callback, bpf_prog_load_integrity(), located within the
security_bpf_prog_load() hook, is necessary to ensure that the integrity
verification callbacks are executed before any of the existing LSMs
are executed via the bpf_prog_load() callback. Reusing the existing
bpf_prog_load() callback for integrity verification could result in LSMs
not having access to the integrity verification results when asked to
authorize the BPF program load in the bpf_prog_load() callback.
The new LSM hook, security_bpf_prog_load_post_integrity(), is intended
to be called from within LSMs performing BPF program integrity
verification. It is used to report the verdict of the integrity
verification to other LSMs enforcing access control policy on BPF
program loads. LSMs enforcing such access controls should register a
bpf_prog_load_post_integrity() callback to receive integrity verdicts.
More information on these new callbacks and hook can be found in the
code comments in this patch.
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
---
include/linux/lsm_hook_defs.h | 5 +++
include/linux/security.h | 25 ++++++++++++
security/security.c | 75 +++++++++++++++++++++++++++++++++--
3 files changed, 102 insertions(+), 3 deletions(-)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 8c42b4bde09c0..4971d3c36d5b4 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -434,6 +434,11 @@ LSM_HOOK(int, 0, bpf_prog, struct bpf_prog *prog)
LSM_HOOK(int, 0, bpf_map_create, struct bpf_map *map, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
LSM_HOOK(void, LSM_RET_VOID, bpf_map_free, struct bpf_map *map)
+LSM_HOOK(int, 0, bpf_prog_load_post_integrity, struct bpf_prog *prog,
+ union bpf_attr *attr, struct bpf_token *token, bool kernel,
+ const struct lsm_id *lsmid, enum lsm_integrity_verdict verdict)
+LSM_HOOK(int, 0, bpf_prog_load_integrity, struct bpf_prog *prog,
+ union bpf_attr *attr, struct bpf_token *token, bool kernel)
LSM_HOOK(int, 0, bpf_prog_load, struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free, struct bpf_prog *prog)
diff --git a/include/linux/security.h b/include/linux/security.h
index ee88dd2d2d1f7..b3fd04baa78d0 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -67,6 +67,7 @@ enum fs_value_type;
struct watch;
struct watch_notification;
struct lsm_ctx;
+struct lsm_id;
/* Default (no) options for the capable function */
#define CAP_OPT_NONE 0x0
@@ -100,6 +101,14 @@ enum lsm_integrity_type {
LSM_INT_FSVERITY_BUILTINSIG_VALID,
};
+enum lsm_integrity_verdict {
+ LSM_INT_VERDICT_NONE = 0,
+ LSM_INT_VERDICT_OK,
+ LSM_INT_VERDICT_UNSIGNED,
+ LSM_INT_VERDICT_PARTIALSIG,
+ LSM_INT_VERDICT_BADSIG,
+};
+
/*
* These are reasons that can be passed to the security_locked_down()
* LSM hook. Lockdown reasons that protect kernel integrity (ie, the
@@ -2270,6 +2279,12 @@ extern int security_bpf_prog(struct bpf_prog *prog);
extern int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
struct bpf_token *token, bool kernel);
extern void security_bpf_map_free(struct bpf_map *map);
+extern int security_bpf_prog_load_post_integrity(struct bpf_prog *prog,
+ union bpf_attr *attr,
+ struct bpf_token *token,
+ bool kernel,
+ const struct lsm_id *lsmid,
+ enum lsm_integrity_verdict verdict);
extern int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel);
extern void security_bpf_prog_free(struct bpf_prog *prog);
@@ -2304,6 +2319,16 @@ static inline int security_bpf_map_create(struct bpf_map *map, union bpf_attr *a
static inline void security_bpf_map_free(struct bpf_map *map)
{ }
+static inline int security_bpf_prog_load_post_integrity(struct bpf_prog *prog,
+ union bpf_attr *attr,
+ struct bpf_token *token,
+ bool kernel,
+ const struct lsm_id *lsmid,
+ enum lsm_integrity_verdict verdict)
+{
+ return 0;
+}
+
static inline int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
diff --git a/security/security.c b/security/security.c
index a26c1474e2e49..bb78f7e45a98f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -5233,6 +5233,50 @@ int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
return rc;
}
+/**
+ * security_bpf_prog_load_post_integrity() - Check if the BPF prog is allowed
+ * @prog: BPF program object
+ * @attr: BPF syscall attributes used to create BPF program
+ * @token: BPF token used to grant user access to BPF subsystem
+ * @kernel: whether or not call originated from kernel
+ * @lsmid: LSM ID of the LSM providing @verdict
+ * @verdict: result of the integrity verification
+ *
+ * See the comment block for the security_bpf_prog_load() LSM hook.
+ *
+ * This LSM hook is intended to be called from within the
+ * bpf_prog_load_integrity() callback that is part of the
+ * security_bpf_prog_load() hook; kernel subsystems outside the scope of the
+ * LSM framework should not call this hook directly.
+ *
+ * If the LSM calling into this hook receives a non-zero error code, it should
+ * return the same error code back to its caller. If this hook returns a zero,
+ * it does not necessarily mean that all of the enabled LSMs have authorized
+ * the BPF program load, as there may be other LSMs implementing BPF integrity
+ * checks which have yet to execute. However, if a zero is returned, the LSM
+ * calling into this hook should continue and return zero back to its caller.
+ *
+ * LSMs which implement the bpf_prog_load_post_integrity() callback and
+ * determine that a particular BPF program load is not authorized may choose to
+ * either return an error code for immediate rejection, or store their decision
+ * in their own LSM state attached to @prog, later returning an error code in
+ * the bpf_prog_load() callback. An immediate error code return is in keeping
+ * with the "fail fast" practice, but waiting until the bpf_prog_load()
+ * callback allows the LSM to consider multiple different integrity verdicts.
+ *
+ * Return: Returns 0 on success, error on failure.
+ */
+int security_bpf_prog_load_post_integrity(struct bpf_prog *prog,
+ union bpf_attr *attr,
+ struct bpf_token *token,
+ bool kernel,
+ const struct lsm_id *lsmid,
+ enum lsm_integrity_verdict verdict)
+{
+ return call_int_hook(bpf_prog_load_post_integrity, prog, attr, token,
+ kernel, lsmid, verdict);
+}
+
/**
* security_bpf_prog_load() - Check if loading of BPF program is allowed
* @prog: BPF program object
@@ -5241,8 +5285,24 @@ int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
* @kernel: whether or not call originated from kernel
*
* Perform an access control check when the kernel loads a BPF program and
- * allocates associated BPF program object. This hook is also responsible for
- * allocating any required LSM state for the BPF program.
+ * allocates the associated BPF program object. This hook is also responsible
+ * for allocating any required LSM state for the BPF program.
+ *
+ * This hook calls two LSM callbacks: bpf_prog_load_integrity() and
+ * bpf_prog_load(). The bpf_prog_load_integrity() callback is for those LSMs
+ * that wish to implement integrity verifications of BPF programs, e.g.
+ * signature verification, while the bpf_prog_load() callback is for general
+ * authorization of the BPF program load. Performing both verification and
+ * authorization in a single callback, with arbitrary LSM ordering, would be
+ * a challenge.
+ *
+ * LSMs which implement the bpf_prog_load_integrity() callback should call into
+ * the security_bpf_prog_load_post_integrity() hook with their integrity
+ * verdict. LSMs which implement BPF program integrity policy can register a
+ * callback for the security_bpf_prog_load_post_integrity() hook and
+ * either update their own internal state based on the verdict, or immediately
+ * reject the BPF program load with an error code. See the comment block for
+ * security_bpf_prog_load_post_integrity() for more information.
*
* Return: Returns 0 on success, error on failure.
*/
@@ -5255,9 +5315,18 @@ int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
if (unlikely(rc))
return rc;
+ rc = call_int_hook(bpf_prog_load_integrity, prog, attr, token, kernel);
+ if (unlikely(rc))
+ goto err;
+
rc = call_int_hook(bpf_prog_load, prog, attr, token, kernel);
if (unlikely(rc))
- security_bpf_prog_free(prog);
+ goto err;
+
+ return rc;
+
+err:
+ security_bpf_prog_free(prog);
return rc;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v4 03/10] crypto: pkcs7: add tests for pkcs7_get_authattr
From: Blaise Boscaccy @ 2026-04-16 17:33 UTC (permalink / raw)
To: Blaise Boscaccy, Jonathan Corbet, Paul Moore, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260416173500.176716-1-bboscaccy@linux.microsoft.com>
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Add example code to the test module pkcs7_key_type.c that verifies a
message and then pulls out a known authenticated attribute.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
Acked-by: David Howells <dhowells@redhat.com>
---
crypto/asymmetric_keys/pkcs7_key_type.c | 44 ++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c
index b930d3bbf1af5..e0b1ce0202f6d 100644
--- a/crypto/asymmetric_keys/pkcs7_key_type.c
+++ b/crypto/asymmetric_keys/pkcs7_key_type.c
@@ -12,6 +12,7 @@
#include <linux/verification.h>
#include <linux/key-type.h>
#include <keys/user-type.h>
+#include <crypto/pkcs7.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PKCS#7 testing key type");
@@ -51,16 +52,57 @@ static int pkcs7_view_content(void *ctx, const void *data, size_t len,
static int pkcs7_preparse(struct key_preparsed_payload *prep)
{
enum key_being_used_for usage = pkcs7_usage;
+ int ret;
+ struct pkcs7_message *pkcs7;
+ const void *data;
+ size_t len;
if (usage >= NR__KEY_BEING_USED_FOR) {
pr_err("Invalid usage type %d\n", usage);
return -EINVAL;
}
- return verify_pkcs7_signature(NULL, 0,
+ ret = verify_pkcs7_signature(NULL, 0,
prep->data, prep->datalen,
VERIFY_USE_SECONDARY_KEYRING, usage,
pkcs7_view_content, prep);
+ if (ret)
+ return ret;
+
+ pkcs7 = pkcs7_parse_message(prep->data, prep->datalen);
+ if (IS_ERR(pkcs7)) {
+ pr_err("pkcs7 parse error\n");
+ return PTR_ERR(pkcs7);
+ }
+
+ /*
+ * the parsed message has no trusted signer, so nothing should
+ * be returned here
+ */
+ ret = pkcs7_get_authattr(pkcs7, OID_messageDigest, &data, &len);
+ if (ret == 0) {
+ pr_err("OID returned when no trust in signer\n");
+ goto out;
+ }
+ /* add trust and check again */
+ ret = verify_pkcs7_message_sig(NULL, 0, pkcs7,
+ VERIFY_USE_SECONDARY_KEYRING, usage,
+ NULL, NULL);
+ if (ret) {
+ pr_err("verify_pkcs7_message_sig failed!!\n");
+ goto out;
+ }
+ /* now we should find the OID */
+ ret = pkcs7_get_authattr(pkcs7, OID_messageDigest, &data, &len);
+ if (ret) {
+ pr_err("Failed to get message digest\n");
+ goto out;
+ }
+ pr_info("Correctly Got message hash, size=%zu\n", len);
+
+ out:
+ pkcs7_free_message(pkcs7);
+ return 0;
}
/*
--
2.53.0
^ permalink raw reply related
* [PATCH v4 02/10] crypto: pkcs7: add ability to extract signed attributes by OID
From: Blaise Boscaccy @ 2026-04-16 17:33 UTC (permalink / raw)
To: Blaise Boscaccy, Jonathan Corbet, Paul Moore, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260416173500.176716-1-bboscaccy@linux.microsoft.com>
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Signers may add any information they like in signed attributes and
sometimes this information turns out to be relevant to specific
signing cases, so add an api pkcs7_get_authattr() to extract the value
of an authenticated attribute by specific OID. The current
implementation is designed for the single signer use case and simply
terminates the search when it finds the relevant OID.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
---
crypto/asymmetric_keys/Makefile | 4 +-
crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 ++++++
crypto/asymmetric_keys/pkcs7_parser.c | 81 +++++++++++++++++++++++++++
include/crypto/pkcs7.h | 4 ++
4 files changed, 106 insertions(+), 1 deletion(-)
create mode 100644 crypto/asymmetric_keys/pkcs7_aa.asn1
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index bc65d3b98dcbf..f99b7169ae7cd 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -53,12 +53,14 @@ clean-files += pkcs8.asn1.c pkcs8.asn1.h
obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o
pkcs7_message-y := \
pkcs7.asn1.o \
+ pkcs7_aa.asn1.o \
pkcs7_parser.o \
pkcs7_trust.o \
pkcs7_verify.o
-$(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h
+$(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h $(obj)/pkcs7_aa.asn1.h
$(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h
+$(obj)/pkcs7_aa.asn1.o: $(obj)/pkcs7_aa.asn1.c $(obj)/pkcs7_aa.asn1.h
#
# PKCS#7 parser testing key
diff --git a/crypto/asymmetric_keys/pkcs7_aa.asn1 b/crypto/asymmetric_keys/pkcs7_aa.asn1
new file mode 100644
index 0000000000000..7a8857bdf56e1
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs7_aa.asn1
@@ -0,0 +1,18 @@
+-- SPDX-License-Identifier: BSD-3-Clause
+--
+-- Copyright (C) 2009 IETF Trust and the persons identified as authors
+-- of the code
+--
+-- https://www.rfc-editor.org/rfc/rfc5652#section-3
+
+AA ::= CHOICE {
+ aaSet [0] IMPLICIT AASet,
+ aaSequence [2] EXPLICIT SEQUENCE OF AuthenticatedAttribute
+}
+
+AASet ::= SET OF AuthenticatedAttribute
+
+AuthenticatedAttribute ::= SEQUENCE {
+ type OBJECT IDENTIFIER ({ pkcs7_aa_note_OID }),
+ values SET OF ANY ({ pkcs7_aa_note_attr })
+}
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 6e3ffdac83ace..d467866f7d930 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,6 +15,7 @@
#include <crypto/public_key.h>
#include "pkcs7_parser.h"
#include "pkcs7.asn1.h"
+#include "pkcs7_aa.asn1.h"
MODULE_DESCRIPTION("PKCS#7 parser");
MODULE_AUTHOR("Red Hat, Inc.");
@@ -211,6 +212,86 @@ int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
}
EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
+struct pkcs7_aa_context {
+ bool found;
+ enum OID oid_to_find;
+ const void *data;
+ size_t len;
+};
+
+int pkcs7_aa_note_OID(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct pkcs7_aa_context *ctx = context;
+ enum OID oid = look_up_OID(value, vlen);
+
+ ctx->found = (oid == ctx->oid_to_find);
+
+ return 0;
+}
+
+int pkcs7_aa_note_attr(void *context, size_t hdrlen,
+ unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct pkcs7_aa_context *ctx = context;
+
+ if (ctx->found) {
+ ctx->data = value;
+ ctx->len = vlen;
+ }
+
+ return 0;
+}
+
+/**
+ * pkcs7_get_authattr - get authenticated attribute by OID
+ * @pkcs7: The preparsed PKCS#7 message
+ * @oid: the enum value of the OID to find
+ * @_data: Place to return a pointer to the attribute value
+ * @_len: length of the attribute value
+ *
+ * Searches the authenticated attributes until one is found with a
+ * matching OID. Note that because the attributes are per signer
+ * there could be multiple signers with different values, but this
+ * routine will simply return the first one in parse order.
+ *
+ * Returns -ENODATA if the attribute can't be found
+ */
+int pkcs7_get_authattr(const struct pkcs7_message *pkcs7,
+ enum OID oid,
+ const void **_data, size_t *_len)
+{
+ struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
+ struct pkcs7_aa_context ctx;
+
+ ctx.data = NULL;
+ ctx.oid_to_find = oid;
+
+ for (; sinfo; sinfo = sinfo->next) {
+ int ret;
+
+ /* only extract OIDs from validated signers */
+ if (!sinfo->verified)
+ continue;
+
+ ret = asn1_ber_decoder(&pkcs7_aa_decoder, &ctx,
+ sinfo->authattrs, sinfo->authattrs_len);
+ if (ret < 0 || ctx.data != NULL)
+ break;
+ }
+
+ if (!ctx.data)
+ return -ENODATA;
+
+ *_data = ctx.data;
+ *_len = ctx.len;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pkcs7_get_authattr);
+
/*
* Note an OID when we find one for later processing when we know how
* to interpret it.
diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h
index 38ec7f5f90411..bd83202cd805c 100644
--- a/include/crypto/pkcs7.h
+++ b/include/crypto/pkcs7.h
@@ -25,6 +25,10 @@ extern void pkcs7_free_message(struct pkcs7_message *pkcs7);
extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
const void **_data, size_t *_datalen,
size_t *_headerlen);
+extern int pkcs7_get_authattr(const struct pkcs7_message *pkcs7,
+ enum OID oid,
+ const void **_data, size_t *_len);
+
/*
* pkcs7_trust.c
--
2.53.0
^ permalink raw reply related
* [PATCH v4 01/10] crypto: pkcs7: add flag for validated trust on a signed info block
From: Blaise Boscaccy @ 2026-04-16 17:33 UTC (permalink / raw)
To: Blaise Boscaccy, Jonathan Corbet, Paul Moore, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260416173500.176716-1-bboscaccy@linux.microsoft.com>
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Allow consumers of struct pkcs7_message to tell if any of the sinfo
fields has passed a trust validation. Note that this does not happen
in parsing, pkcs7_validate_trust() must be explicitly called or called
via validate_pkcs7_trust(). Since the way to get this trusted pkcs7
object is via verify_pkcs7_message_sig, export that so modules can use
it.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
---
certs/system_keyring.c | 1 +
crypto/asymmetric_keys/pkcs7_parser.h | 1 +
crypto/asymmetric_keys/pkcs7_trust.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index e0761436ec7f4..9bda49295bd02 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -380,6 +380,7 @@ int verify_pkcs7_message_sig(const void *data, size_t len,
pr_devel("<==%s() = %d\n", __func__, ret);
return ret;
}
+EXPORT_SYMBOL(verify_pkcs7_message_sig);
/**
* verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
index 6ef9f335bb17f..203062a33def6 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.h
+++ b/crypto/asymmetric_keys/pkcs7_parser.h
@@ -20,6 +20,7 @@ struct pkcs7_signed_info {
unsigned index;
bool unsupported_crypto; /* T if not usable due to missing crypto */
bool blacklisted;
+ bool verified; /* T if this signer has validated trust */
/* Message digest - the digest of the Content Data (or NULL) */
const void *msgdigest;
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 9a87c34ed1733..78ebfb6373b61 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -127,6 +127,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
for (p = sinfo->signer; p != x509; p = p->signer)
p->verified = true;
}
+ sinfo->verified = true;
kleave(" = 0");
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v4 00/10] Reintroduce Hornet LSM
From: Blaise Boscaccy @ 2026-04-16 17:33 UTC (permalink / raw)
To: Blaise Boscaccy, Jonathan Corbet, Paul Moore, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
This patch series introduces the next iteration of the Hornet LSM.
Hornet’s goal is to provide a secure and extensible in-kernel
signature verification mechanism for eBPF programs.
Hornet addresses concerns from users who require strict audit trails and
verification guarantees for eBPF programs, especially in
security-sensitive environments. Many production systems need assurance
that only authorized, unmodified eBPF programs are loaded into the
kernel. Hornet provides this assurance through cryptographic signature
verification.
The currently accepted loader-plus-map signature verification scheme,
mandated by Alexei and KP, is simple to implement and generally
acceptable if users and administrators are satisfied with it. However,
verifying both the loader and the maps offers additional benefits
beyond verifying the loader alone:
1. Security and Audit Integrity
A key advantage is that the LSM hook for authorizing BPF program loads
can operate after signature verification. This ensures:
* Access control decisions are based on verified signature status.
* Accurate system state measurement and logging.
* Log entries claiming a verified signature are truthful, avoiding
misleading records where only the loader was verified while the actual
BPF program verification occurs later without logging.
2. TOCTOU Attack Prevention
The current map hash implementation may be vulnerable to a TOCTOU
attack because it allows unfrozen maps to cache a previously
calculated hash. The accepted “trusted loader” scheme cannot detect
this and may permit loading altered maps.
3. Supply Chain Integrity
Verify that eBPF programs and their associated map data have not been
modified since they were built and signed, in the kernel proper, may
aid in protecting against supply chain attacks.
This approach addresses concerns from users who require strict audit
trails and verification guarantees, especially in security-sensitive
environments. Map hashes for extended verification are passed via the
existing PKCS#7 UAPI and verified by the crypto subsystem. Hornet then
calculates the program’s verification state. Hornet itself does not
enforce a policy on whether unsigned or partially signed programs
should be rejected. It delegates that decision to downstream LSMs
hook, making it a composable building block in a larger security
architecture.
Changes in V4:
- IPE integration
- Arbitrary keyring support
Link to V3: https://lore.kernel.org/linux-security-module/20260326060655.2550595-1-bboscaccy@linux.microsoft.com/
Changes in V3:
- Updated for signed attribute patch series changes
- Added some new result enum values
- Minor documentation clarification
- Misc style fixes
- Added missing signed-off-by tags
Link to V2: https://lore.kernel.org/linux-security-module/20260227233930.2418522-1-bboscaccy@linux.microsoft.com/
Changes in V2:
- Addressed possible TocTou races in hash verification
- Improved documentation and tooling
- Added Alexie's nack
Link to RFC: https://lore.kernel.org/linux-security-module/20251211021257.1208712-1-bboscaccy@linux.microsoft.com/
Blaise Boscaccy (6):
lsm: security: Add additional enum values for bpf integrity checks
security: Hornet LSM
hornet: Introduce gen_sig
hornet: Add a light skeleton data extractor scripts
selftests/hornet: Add a selftest for the Hornet LSM
ipe: Add BPF program load policy enforcement via Hornet integration
James Bottomley (3):
crypto: pkcs7: add flag for validated trust on a signed info block
crypto: pkcs7: add ability to extract signed attributes by OID
crypto: pkcs7: add tests for pkcs7_get_authattr
Paul Moore (1):
lsm: framework for BPF integrity verification
Documentation/admin-guide/LSM/Hornet.rst | 321 +++++++++++++++
Documentation/admin-guide/LSM/index.rst | 1 +
MAINTAINERS | 9 +
certs/system_keyring.c | 1 +
crypto/asymmetric_keys/Makefile | 4 +-
crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 +
crypto/asymmetric_keys/pkcs7_key_type.c | 44 ++-
crypto/asymmetric_keys/pkcs7_parser.c | 81 ++++
crypto/asymmetric_keys/pkcs7_parser.h | 1 +
crypto/asymmetric_keys/pkcs7_trust.c | 1 +
include/crypto/pkcs7.h | 4 +
include/linux/lsm_hook_defs.h | 5 +
include/linux/oid_registry.h | 3 +
include/linux/security.h | 28 ++
include/uapi/linux/lsm.h | 1 +
scripts/Makefile | 1 +
scripts/hornet/Makefile | 5 +
scripts/hornet/extract-insn.sh | 27 ++
scripts/hornet/extract-map.sh | 27 ++
scripts/hornet/extract-skel.sh | 27 ++
scripts/hornet/gen_sig.c | 392 +++++++++++++++++++
scripts/hornet/write-sig.sh | 27 ++
security/Kconfig | 3 +-
security/Makefile | 1 +
security/hornet/Kconfig | 11 +
security/hornet/Makefile | 7 +
security/hornet/hornet.asn1 | 13 +
security/hornet/hornet_lsm.c | 346 ++++++++++++++++
security/ipe/Kconfig | 14 +
security/ipe/audit.c | 15 +
security/ipe/eval.c | 73 +++-
security/ipe/eval.h | 5 +
security/ipe/hooks.c | 37 ++
security/ipe/hooks.h | 11 +
security/ipe/ipe.c | 3 +
security/ipe/policy.h | 14 +
security/ipe/policy_parser.c | 27 ++
security/security.c | 75 +++-
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/hornet/Makefile | 63 +++
tools/testing/selftests/hornet/loader.c | 21 +
tools/testing/selftests/hornet/trivial.bpf.c | 33 ++
42 files changed, 1794 insertions(+), 7 deletions(-)
create mode 100644 Documentation/admin-guide/LSM/Hornet.rst
create mode 100644 crypto/asymmetric_keys/pkcs7_aa.asn1
create mode 100644 scripts/hornet/Makefile
create mode 100755 scripts/hornet/extract-insn.sh
create mode 100755 scripts/hornet/extract-map.sh
create mode 100755 scripts/hornet/extract-skel.sh
create mode 100644 scripts/hornet/gen_sig.c
create mode 100755 scripts/hornet/write-sig.sh
create mode 100644 security/hornet/Kconfig
create mode 100644 security/hornet/Makefile
create mode 100644 security/hornet/hornet.asn1
create mode 100644 security/hornet/hornet_lsm.c
create mode 100644 tools/testing/selftests/hornet/Makefile
create mode 100644 tools/testing/selftests/hornet/loader.c
create mode 100644 tools/testing/selftests/hornet/trivial.bpf.c
--
2.53.0
^ permalink raw reply
* [PATCH v3 0/4] Add support for ML-DSA signature for EVM and IMA
From: Stefan Berger @ 2026-04-16 15:40 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
Based on IMA sigv3 type of signatures, add support for ML-DSA signature
for EVM and IMA. Use the existing ML-DSA hashless signing mode (pure mode).
Stefan
v3:
- new patches 1/4 and 2/4
- addressed Mimi's comments on v2
v2:
- Dropped 1/3
- Using "none" as hash_algo in 2/2
Stefan Berger (4):
integrity: Check for NULL returned by asymmetric_key_public_key
integrity: Check that algo parameter is within valid range
integrity: Refactor asymmetric_verify for reusability
integrity: Add support for sigv3 verification using ML-DSA keys
security/integrity/digsig_asymmetric.c | 152 +++++++++++++++++++++----
1 file changed, 131 insertions(+), 21 deletions(-)
base-commit: 82bbd447199ff1441031d2eaf9afe041550cf525
--
2.53.0
^ permalink raw reply
* [PATCH v3 3/4] integrity: Refactor asymmetric_verify for reusability
From: Stefan Berger @ 2026-04-16 15:40 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
In-Reply-To: <20260416154039.1648083-1-stefanb@linux.ibm.com>
Refactor asymmetric_verify for reusability. Have it call
asymmetric_verify_common with the signature verification key and the
public_key structure as parameters. sigv3 support for ML-DSA will need to
check the public key type first to decide how to do the signature
verification and therefore will have these parameters available for
calling asymmetric_verify_common.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
v3:
- added kernel-doc
- NULL pointer check on asymmetric_key_public_key return value
---
security/integrity/digsig_asymmetric.c | 62 ++++++++++++++++++--------
1 file changed, 43 insertions(+), 19 deletions(-)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index ed171a627d18..a4eb73bba6d2 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -79,18 +79,25 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
return key;
}
-int asymmetric_verify(struct key *keyring, const char *sig,
- int siglen, const char *data, int datalen)
+/**
+ * asymmetric_verify_common -- sigv2 and sigv3 common verify function
+ * @key: The key to use for signature verification; caller must free it
+ * @pk: The associated public key; must not be NULL
+ * @sig: The xattr signature
+ * @siglen: The length of the xattr signature; must be at least
+ * sizeof(struct signature_v2_hdr)
+ * @data: The data to verify the signature on
+ * @datalen: Length of @data
+ */
+static int asymmetric_verify_common(const struct key *key,
+ const struct public_key *pk,
+ const char *sig, int siglen,
+ const char *data, int datalen)
{
- struct public_key_signature pks;
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
- const struct public_key *pk;
- struct key *key;
+ struct public_key_signature pks;
int ret;
- if (siglen <= sizeof(*hdr))
- return -EBADMSG;
-
siglen -= sizeof(*hdr);
if (siglen != be16_to_cpu(hdr->sig_size))
@@ -99,19 +106,9 @@ int asymmetric_verify(struct key *keyring, const char *sig,
if (hdr->hash_algo >= HASH_ALGO__LAST)
return -ENOPKG;
- key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
- if (IS_ERR(key))
- return PTR_ERR(key);
-
memset(&pks, 0, sizeof(pks));
pks.hash_algo = hash_algo_name[hdr->hash_algo];
-
- pk = asymmetric_key_public_key(key);
- if (!pk) {
- ret = -ENOKEY;
- goto out;
- }
pks.pkey_algo = pk->pkey_algo;
if (!strcmp(pk->pkey_algo, "rsa")) {
pks.encoding = "pkcs1";
@@ -131,11 +128,38 @@ int asymmetric_verify(struct key *keyring, const char *sig,
pks.s_size = siglen;
ret = verify_signature(key, &pks);
out:
- key_put(key);
pr_debug("%s() = %d\n", __func__, ret);
return ret;
}
+int asymmetric_verify(struct key *keyring, const char *sig,
+ int siglen, const char *data, int datalen)
+{
+ struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
+ const struct public_key *pk;
+ struct key *key;
+ int ret;
+
+ if (siglen <= sizeof(*hdr))
+ return -EBADMSG;
+
+ key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+ pk = asymmetric_key_public_key(key);
+ if (!pk) {
+ ret = -ENOKEY;
+ goto out;
+ }
+
+ ret = asymmetric_verify_common(key, pk, sig, siglen, data, datalen);
+
+out:
+ key_put(key);
+
+ return ret;
+}
+
/*
* calc_file_id_hash - calculate the hash of the ima_file_id struct data
* @type: xattr type [enum evm_ima_xattr_type]
--
2.53.0
^ permalink raw reply related
* [PATCH v3 4/4] integrity: Add support for sigv3 verification using ML-DSA keys
From: Stefan Berger @ 2026-04-16 15:40 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
In-Reply-To: <20260416154039.1648083-1-stefanb@linux.ibm.com>
Add support for sigv3 signature verification using ML-DSA in pure mode.
When a sigv3 signature is verified, first check whether the key to use
for verification is an ML-DSA key and therefore uses a hashless signature
verification scheme. The hashless signature verification method uses the
ima_file_id structure directly for signature verification rather than
its digest.
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
v3:
- Renamed err_exit label to 'out'
- Updated kernel-doc for new function
- Relying on algo verified by caller of asymmetric_verify_v3_hashless
- NULL pointer check on asymmetric_key_public_key return value
v2: Set hash_algo in public_key_signature to "none"
---
security/integrity/digsig_asymmetric.c | 89 ++++++++++++++++++++++++--
1 file changed, 84 insertions(+), 5 deletions(-)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index a4eb73bba6d2..b4c23a0ed68f 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -204,20 +204,99 @@ static int calc_file_id_hash(enum evm_ima_xattr_type type,
return rc;
}
+/**
+ * asymmetric_verify_v3_hashless - Use hashless signature verification on sigv3
+ * @key: The key to use for signature verification; caller must free it
+ * @pk: The associated public key; must not be NULL
+ * @encoding: The encoding the key type uses
+ * @sig: The xattr signature
+ * @siglen: The length of the xattr signature; must be at least
+ * sizeof(struct signature_v2_hdr)
+ * @algo: hash algorithm [enum hash_algo]; caller must ensure valid value
+ * @digest: The file digest
+ *
+ * Create an ima_file_id structure and use it for signature verification
+ * directly. This can be used for ML-DSA in pure mode for example.
+ */
+static int asymmetric_verify_v3_hashless(struct key *key,
+ const struct public_key *pk,
+ const char *encoding,
+ const char *sig, int siglen,
+ u8 algo,
+ const u8 *digest)
+{
+ struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
+ struct ima_file_id file_id = {
+ .hash_type = hdr->type,
+ .hash_algorithm = algo,
+ };
+ size_t digest_size = hash_digest_size[algo];
+ struct public_key_signature pks = {
+ .m = (u8 *)&file_id,
+ .m_size = sizeof(file_id) - (HASH_MAX_DIGESTSIZE - digest_size),
+ .s = hdr->sig,
+ .s_size = siglen - sizeof(*hdr),
+ .pkey_algo = pk->pkey_algo,
+ .hash_algo = "none",
+ .encoding = encoding,
+ };
+ int ret;
+
+ if (hdr->type != IMA_VERITY_DIGSIG &&
+ hdr->type != EVM_IMA_XATTR_DIGSIG &&
+ hdr->type != EVM_XATTR_PORTABLE_DIGSIG)
+ return -EINVAL;
+
+ if (pks.s_size != be16_to_cpu(hdr->sig_size))
+ return -EBADMSG;
+
+ memcpy(file_id.hash, digest, digest_size);
+
+ ret = verify_signature(key, &pks);
+ pr_debug("%s() = %d\n", __func__, ret);
+ return ret;
+}
+
int asymmetric_verify_v3(struct key *keyring, const char *sig, int siglen,
const char *data, int datalen, u8 algo)
{
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
struct ima_max_digest_data hash;
+ const struct public_key *pk;
+ struct key *key;
int rc;
if (algo >= HASH_ALGO__LAST)
return -ENOPKG;
- rc = calc_file_id_hash(hdr->type, algo, data, &hash);
- if (rc)
- return -EINVAL;
+ if (siglen <= sizeof(*hdr))
+ return -EBADMSG;
- return asymmetric_verify(keyring, sig, siglen, hash.digest,
- hash.hdr.length);
+ key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+
+ pk = asymmetric_key_public_key(key);
+ if (!pk) {
+ rc = -ENOKEY;
+ goto out;
+ }
+ if (!strncmp(pk->pkey_algo, "mldsa", 5)) {
+ rc = asymmetric_verify_v3_hashless(key, pk, "raw",
+ sig, siglen, algo, data);
+ } else {
+ rc = calc_file_id_hash(hdr->type, algo, data, &hash);
+ if (rc) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = asymmetric_verify_common(key, pk, sig, siglen, hash.digest,
+ hash.hdr.length);
+ }
+
+out:
+ key_put(key);
+
+ return rc;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/4] integrity: Check that algo parameter is within valid range
From: Stefan Berger @ 2026-04-16 15:40 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
In-Reply-To: <20260416154039.1648083-1-stefanb@linux.ibm.com>
Check that the algo parameter passed to calc_file_id_hash is within valid
range. Do this in asymmetric_verify_v3 since this value will also be passed
to a hashless signature verification function from here.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
security/integrity/digsig_asymmetric.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index a791ad43b3fb..ed171a627d18 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -139,7 +139,7 @@ int asymmetric_verify(struct key *keyring, const char *sig,
/*
* calc_file_id_hash - calculate the hash of the ima_file_id struct data
* @type: xattr type [enum evm_ima_xattr_type]
- * @algo: hash algorithm [enum hash_algo]
+ * @algo: hash algorithm [enum hash_algo]; caller must ensure valid value
* @digest: pointer to the digest to be hashed
* @hash: (out) pointer to the hash
*
@@ -187,6 +187,9 @@ int asymmetric_verify_v3(struct key *keyring, const char *sig, int siglen,
struct ima_max_digest_data hash;
int rc;
+ if (algo >= HASH_ALGO__LAST)
+ return -ENOPKG;
+
rc = calc_file_id_hash(hdr->type, algo, data, &hash);
if (rc)
return -EINVAL;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 1/4] integrity: Check for NULL returned by asymmetric_key_public_key
From: Stefan Berger @ 2026-04-16 15:40 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
In-Reply-To: <20260416154039.1648083-1-stefanb@linux.ibm.com>
Check for a NULL pointer returned by asymmetric_key_public_key and return
-ENOKEY in this case.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
security/integrity/digsig_asymmetric.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 6e68ec3becbd..a791ad43b3fb 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -108,6 +108,10 @@ int asymmetric_verify(struct key *keyring, const char *sig,
pks.hash_algo = hash_algo_name[hdr->hash_algo];
pk = asymmetric_key_public_key(key);
+ if (!pk) {
+ ret = -ENOKEY;
+ goto out;
+ }
pks.pkey_algo = pk->pkey_algo;
if (!strcmp(pk->pkey_algo, "rsa")) {
pks.encoding = "pkcs1";
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 01/61] Coccinelle: Prefer IS_ERR_OR_NULL over manual NULL check
From: Krzysztof Kozlowski @ 2026-04-16 12:30 UTC (permalink / raw)
To: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
linux-s390, linux-scsi, linux-sctp, linux-security-module,
linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
target-devel, tipc-discussion, v9fs
Cc: Julia Lawall, Nicolas Palix
In-Reply-To: <20260310-b4-is_err_or_null-v1-1-bd63b656022d@avm.de>
On 10/03/2026 12:48, Philipp Hahn wrote:
> Find and convert uses of IS_ERR() plus NULL check to IS_ERR_OR_NULL().
>
> There are several cases where `!ptr && WARN_ON[_ONCE](IS_ERR(ptr))` is
> used:
> - arch/x86/kernel/callthunks.c:215 WARN_ON_ONCE
> - drivers/clk/clk.c:4561 WARN_ON_ONCE
> - drivers/interconnect/core.c:793 WARN_ON
> - drivers/reset/core.c:718 WARN_ON
> The change is not 100% semantical equivalent as the warning will now
> also happen when the pointer is NULL.
>
> To: Julia Lawall <Julia.Lawall@inria.fr>
> To: Nicolas Palix <nicolas.palix@imag.fr>
> Cc: cocci@inria.fr
> Cc: linux-kernel@vger.kernel.org
>
> ---
> drivers/clocksource/mips-gic-timer.c:283 looks suspicious: ret != clk,
> but Daniel Lezcano verified it as cottect.
>
> There are some cases where the checks are part of a larger expression:
> - mm/kmemleak.c:1095
> - mm/kmemleak.c:1155
> - mm/kmemleak.c:1173
> - mm/kmemleak.c:1290
> - mm/kmemleak.c:1328
> - mm/kmemleak.c:1241
> - mm/kmemleak.c:1310
> - mm/kmemleak.c:1258
> - net/netlink/af_netlink.c:2670
> Thanks to Julia Lawall for the help to also handle them.
>
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
> scripts/coccinelle/api/is_err_or_null.cocci | 125 ++++++++++++++++++++++++++++
> 1 file changed, 125 insertions(+)
>
Neither this, nor try from 2011, nor any future try should be accepted,
because it creates impression IS_ERR_OR_NULL is somehow okay. No, it is
not okay, it is a discouraged pattern leading to less readable and
maintainable code. We should not have therefore any tools suggesting
usage of IS_ERR_OR_NULL, because people will be converting poor code
into that, instead of fixing that poor code.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 55/61] interconnect: Prefer IS_ERR_OR_NULL over manual NULL check
From: Krzysztof Kozlowski @ 2026-04-16 12:24 UTC (permalink / raw)
To: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
linux-s390, linux-scsi, linux-sctp, linux-security-module,
linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
target-devel, tipc-discussion, v9fs
Cc: Georgi Djakov
In-Reply-To: <20260310-b4-is_err_or_null-v1-55-bd63b656022d@avm.de>
On 10/03/2026 12:49, Philipp Hahn wrote:
> Prefer using IS_ERR_OR_NULL() over using IS_ERR() and a manual NULL
> check.
>
> Semantich change: Previously the code only printed the warning on error,
> but not when the pointer was NULL. Now the warning is printed in both
> cases!
NAK, read the code
>
> Change found with coccinelle.
>
> To: Georgi Djakov <djakov@kernel.org>
> Cc: linux-pm@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
> drivers/interconnect/core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
> index 8569b78a18517b33abeafac091978b25cbc1acc7..22e92b30f73853d5bd2e05b4f52cb5aa22556468 100644
> --- a/drivers/interconnect/core.c
> +++ b/drivers/interconnect/core.c
> @@ -790,7 +790,7 @@ void icc_put(struct icc_path *path)
> size_t i;
> int ret;
>
> - if (!path || WARN_ON(IS_ERR(path)))
> + if (WARN_ON(IS_ERR_OR_NULL(path)))
IS_ERR_OR_NULL is simply discouraged, but beside of code preference, you
just added bug here. This is clearly not equivalent and you emit warn on
perfectly valid case!
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v4] KEYS: trusted: Debugging as a feature
From: Nayna Jain @ 2026-04-16 3:16 UTC (permalink / raw)
To: Jarkko Sakkinen, linux-integrity
Cc: Srish Srinivasan, Jonathan Corbet, Shuah Khan, James Bottomley,
Mimi Zohar, David Howells, Paul Moore, James Morris,
Serge E. Hallyn, Ahmad Fatoum, Pengutronix Kernel Team,
Andrew Morton, Borislav Petkov (AMD), Randy Dunlap, Dave Hansen,
Pawan Gupta, Feng Tang, Dapeng Mi, Kees Cook, Marco Elver,
Li RongQing, Paul E. McKenney, Thomas Gleixner, Bjorn Helgaas,
linux-doc, linux-kernel, keyrings, linux-security-module
In-Reply-To: <20260415111202.63888-1-jarkko@kernel.org>
On 4/15/26 7:12 AM, Jarkko Sakkinen wrote:
> TPM_DEBUG, and other similar flags, are a non-standard way to specify a
> feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for trusted
> keys, and use it to replace these ad-hoc feature flags.
>
> Given that trusted keys debug dumps can contain sensitive data, harden the
> feature as follows:
>
> 1. In the Kconfig description postulate that pr_debug() statements must be
> used.
> 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
> 3. Require trusted.debug=1 on the kernel command line (default: 0) to
> activate dumps at runtime, even when CONFIG_TRUSTED_KEYS_DEBUG=y.
>
> Traces, when actually needed, can be easily enabled by providing
> trusted.dyndbg='+p' and trusted.debug=1 in the kernel command-line.
Thanks for adding the documentation.
Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
>
> Reported-by: Nayna Jain <nayna@linux.ibm.com>
> Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
> Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
> Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
> ---
> v4:
> - Added kernel parameter documentation.t
> - Added tags from Srishand and Nayna.
> - Sanity check round. This version will be applied unless there is
> something specific to address.
> v3:
> - Add kernel-command line option for enabling the traces.
> - Add safety information to the Kconfig entry.
> v2:
> - Implement for all trusted keys backends.
> - Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
> coverage.
> ---
> .../admin-guide/kernel-parameters.txt | 16 +++++++
> include/keys/trusted-type.h | 21 +++++----
> security/keys/trusted-keys/Kconfig | 23 ++++++++++
> security/keys/trusted-keys/trusted_caam.c | 7 ++-
> security/keys/trusted-keys/trusted_core.c | 6 +++
> security/keys/trusted-keys/trusted_tpm1.c | 44 +++++++++++--------
> 6 files changed, 87 insertions(+), 30 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index f2ce1f4975c1..f1515668c8ab 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -7917,6 +7917,22 @@ Kernel parameters
> first trust source as a backend which is initialized
> successfully during iteration.
>
> + trusted.debug= [KEYS]
> + Format: <bool>
> + Enable trusted keys debug traces at runtime when
> + CONFIG_TRUSTED_KEYS_DEBUG=y.
> +
> + To make the traces visible after enabling the option,
> + use trusted.dyndbg='+p' as needed. By convention,
> + the subsystem uses pr_debug() for these traces.
> +
> + SAFETY: The traces can leak sensitive data, so be
> + cautious before enabling this. They remain inactive
> + unless this parameter is set this option to a true
> + value.
> +
> + Default: false
> +
> trusted.rng= [KEYS]
> Format: <string>
> The RNG used to generate key material for trusted keys.
> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> index 03527162613f..9f9940482da4 100644
> --- a/include/keys/trusted-type.h
> +++ b/include/keys/trusted-type.h
> @@ -83,18 +83,21 @@ struct trusted_key_source {
>
> extern struct key_type key_type_trusted;
>
> -#define TRUSTED_DEBUG 0
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> +extern bool trusted_debug;
>
> -#if TRUSTED_DEBUG
> static inline void dump_payload(struct trusted_key_payload *p)
> {
> - pr_info("key_len %d\n", p->key_len);
> - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
> - 16, 1, p->key, p->key_len, 0);
> - pr_info("bloblen %d\n", p->blob_len);
> - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
> - 16, 1, p->blob, p->blob_len, 0);
> - pr_info("migratable %d\n", p->migratable);
> + if (!trusted_debug)
> + return;
> +
> + pr_debug("key_len %d\n", p->key_len);
> + print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
> + 16, 1, p->key, p->key_len, 0);
> + pr_debug("bloblen %d\n", p->blob_len);
> + print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
> + 16, 1, p->blob, p->blob_len, 0);
> + pr_debug("migratable %d\n", p->migratable);
> }
> #else
> static inline void dump_payload(struct trusted_key_payload *p)
> diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
> index 9e00482d886a..e5a4a53aeab2 100644
> --- a/security/keys/trusted-keys/Kconfig
> +++ b/security/keys/trusted-keys/Kconfig
> @@ -1,10 +1,29 @@
> config HAVE_TRUSTED_KEYS
> bool
>
> +config HAVE_TRUSTED_KEYS_DEBUG
> + bool
> +
> +config TRUSTED_KEYS_DEBUG
> + bool "Debug trusted keys"
> + depends on HAVE_TRUSTED_KEYS_DEBUG
> + default n
> + help
> + Trusted key backends and core code that support debug traces can
> + opt-in that feature here. Traces must only use debug level output, as
> + sensitive data may pass by. In the kernel-command line traces can be
> + enabled via trusted.dyndbg='+p'.
> +
> + SAFETY: Debug dumps are inactive at runtime until trusted.debug is set
> + to a true value on the kernel command-line. Use at your utmost
> + consideration when enabling this feature on a production build. The
> + general advice is not to do this.
> +
> config TRUSTED_KEYS_TPM
> bool "TPM-based trusted keys"
> depends on TCG_TPM >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select CRYPTO_HASH_INFO
> select CRYPTO_LIB_SHA1
> select CRYPTO_LIB_UTILS
> @@ -23,6 +42,7 @@ config TRUSTED_KEYS_TEE
> bool "TEE-based trusted keys"
> depends on TEE >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of the Trusted Execution Environment (TEE) as trusted
> @@ -33,6 +53,7 @@ config TRUSTED_KEYS_CAAM
> depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
> select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of NXP's Cryptographic Accelerator and Assurance Module
> @@ -42,6 +63,7 @@ config TRUSTED_KEYS_DCP
> bool "DCP-based trusted keys"
> depends on CRYPTO_DEV_MXS_DCP >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of NXP's DCP (Data Co-Processor) as trusted key backend.
> @@ -50,6 +72,7 @@ config TRUSTED_KEYS_PKWM
> bool "PKWM-based trusted keys"
> depends on PSERIES_PLPKS >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of IBM PowerVM Key Wrapping Module (PKWM) as a trusted key backend.
> diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
> index 601943ce0d60..6a33dbf2a7f5 100644
> --- a/security/keys/trusted-keys/trusted_caam.c
> +++ b/security/keys/trusted-keys/trusted_caam.c
> @@ -28,10 +28,13 @@ static const match_table_t key_tokens = {
> {opt_err, NULL}
> };
>
> -#ifdef CAAM_DEBUG
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> static inline void dump_options(const struct caam_pkey_info *pkey_info)
> {
> - pr_info("key encryption algo %d\n", pkey_info->key_enc_algo);
> + if (!trusted_debug)
> + return;
> +
> + pr_debug("key encryption algo %d\n", pkey_info->key_enc_algo);
> }
> #else
> static inline void dump_options(const struct caam_pkey_info *pkey_info)
> diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
> index 0b142d941cd2..6aed17bee09d 100644
> --- a/security/keys/trusted-keys/trusted_core.c
> +++ b/security/keys/trusted-keys/trusted_core.c
> @@ -31,6 +31,12 @@ static char *trusted_rng = "default";
> module_param_named(rng, trusted_rng, charp, 0);
> MODULE_PARM_DESC(rng, "Select trusted key RNG");
>
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> +bool trusted_debug;
> +module_param_named(debug, trusted_debug, bool, 0);
> +MODULE_PARM_DESC(debug, "Enable trusted keys debug traces (default: 0)");
> +#endif
> +
> static char *trusted_key_source;
> module_param_named(source, trusted_key_source, charp, 0);
> MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam, dcp or pkwm)");
> diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
> index 6ea728f1eae6..13513819991e 100644
> --- a/security/keys/trusted-keys/trusted_tpm1.c
> +++ b/security/keys/trusted-keys/trusted_tpm1.c
> @@ -46,38 +46,44 @@ enum {
> SRK_keytype = 4
> };
>
> -#define TPM_DEBUG 0
> -
> -#if TPM_DEBUG
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> static inline void dump_options(struct trusted_key_options *o)
> {
> - pr_info("sealing key type %d\n", o->keytype);
> - pr_info("sealing key handle %0X\n", o->keyhandle);
> - pr_info("pcrlock %d\n", o->pcrlock);
> - pr_info("pcrinfo %d\n", o->pcrinfo_len);
> - print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
> - 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
> + if (!trusted_debug)
> + return;
> +
> + pr_debug("sealing key type %d\n", o->keytype);
> + pr_debug("sealing key handle %0X\n", o->keyhandle);
> + pr_debug("pcrlock %d\n", o->pcrlock);
> + pr_debug("pcrinfo %d\n", o->pcrinfo_len);
> + print_hex_dump_debug("pcrinfo ", DUMP_PREFIX_NONE,
> + 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
> }
>
> static inline void dump_sess(struct osapsess *s)
> {
> - print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
> - 16, 1, &s->handle, 4, 0);
> - pr_info("secret:\n");
> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
> - 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
> - pr_info("trusted-key: enonce:\n");
> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
> - 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
> + if (!trusted_debug)
> + return;
> +
> + print_hex_dump_debug("trusted-key: handle ", DUMP_PREFIX_NONE,
> + 16, 1, &s->handle, 4, 0);
> + pr_debug("secret:\n");
> + print_hex_dump_debug("", DUMP_PREFIX_NONE,
> + 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
> + pr_debug("trusted-key: enonce:\n");
> + print_hex_dump_debug("", DUMP_PREFIX_NONE,
> + 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
> }
>
> static inline void dump_tpm_buf(unsigned char *buf)
> {
> int len;
>
> - pr_info("\ntpm buffer\n");
> + if (!trusted_debug)
> + return;
> + pr_debug("\ntpm buffer\n");
> len = LOAD32(buf, TPM_SIZE_OFFSET);
> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
> + print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
> }
> #else
> static inline void dump_options(struct trusted_key_options *o)
^ permalink raw reply
* 社長のNG行動
From: 神田/ナレッジリンク @ 2026-04-16 3:05 UTC (permalink / raw)
To: linux-security-module
お世話になります。ナレッジリンクセミナー事務局です。
「社員のモチベーションを上げようと声をかける」
「部下の相談に乗り、一緒に悩んであげる」
「現場のトラブルに、自ら先頭に立って対応する」
もし社長がこれらを率先しているようであれば、
残念ながら、その組織の成長はそこで止まります。
社長のその“優しさ”が、社員の甘えを生み、責任感を奪い、
「指示待ち人間」を量産する装置になっているからです。
4,800社の経営者が衝撃を受けた、
良かれと思ってやってしまう「社長のNG行動」の正体。
組織を劇的に変えるための、
オンラインセミナーを開催いたします。
1つでも心当たりがあれば、一度ご視聴ください。
>>視聴予約はこちら
https://knowledge-corp.jp/shikigaku5/
----------------------------------------------
テーマ : それ、危険です 『社長のNG行動』
〜 その行動が、組織崩壊を招く 〜
日 程 : 4月21日(火)13:00スタート ※残11席
5月19日(火)13:00スタート
※どちらの日程も内容は同じ
会 場 :Zoom開催
定 員 :先着100名(費用は不要)
----------------------------------------------
※経営層の方限定です
なぜ、社員は「言われたこと」しかやらないのか。
なぜ、次世代のリーダー候補が育たないのか。
それは、能力の問題ではなく、
良かれと思って続けている「社長の配慮」こそが、
組織成長を止める、最大のボトルネックかもしれません。
本セミナーでは、4,800社以上が導入した
独自の組織論「識学」に基づき、社長の「NG行動」と
真の経営者へ脱皮するためのマインドセットを伝授します。
【セミナー内容(一部抜粋)】
○ NG行動3選
○ なぜ優秀なNo.2や部長が育たないのか
○ マネジメントスタイルの変革について
○ 導入企業の事例
「管理職が育ったら任せる」ではなく「任せるから育つ」
という思考の逆転を提言。
現場から「冷たくなった」と思われることを恐れず、
機能的な階層構造(仕組み)を作ることで
結果として社員全員を守り、
利益を最大化させる道筋を明示します。
「優しさ」で人を動かすのではなく、
「正しさ」で組織を動かす。
音声やお顔が表に出ることはございませんので
お気軽にご視聴ください。
>>視聴予約はこちら
https://knowledge-corp.jp/shikigaku5/
-----------------------
一般社団法人 ナレッジリンク
東京都千代田区神田小川町1-8-3
電話:03-5256-7638
セミナーのご案内が不要な方は大変残念ではございますが、
下記URLより手続き下さいませ。
メール配信のワンクリック解除はこちら
https://fc-knowledgelink-corp.jp/mail/
^ permalink raw reply
* Re: [GIT PULL] IPE update for 7.1
From: pr-tracker-bot @ 2026-04-15 22:37 UTC (permalink / raw)
To: Fan Wu; +Cc: torvalds, Linux Kernel Mailing List, linux-security-module
In-Reply-To: <CAKtyLkHLk0o+fqLOjf2F9_ixkcgjW6rDpARQs0H7GPn+OJ2c4g@mail.gmail.com>
The pull request you sent on Mon, 13 Apr 2026 16:11:23 -0700:
> git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe.git tags/ipe-pr-20260413
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/8801e23b5b0dcf7d9c2291cc0901628dc1006145
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH v2 0/4] Firmware LSM hook
From: Paul Moore @ 2026-04-15 21:40 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Leon Romanovsky, Roberto Sassu, KP Singh, Matt Bobrowski,
Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, Stanislav Fomichev, Hao Luo, Jiri Olsa, Shuah Khan,
Saeed Mahameed, Itay Avraham, Dave Jiang, Jonathan Cameron, bpf,
linux-kernel, linux-kselftest, linux-rdma, Chiara Meiohas,
Maher Sanalla, linux-security-module
In-Reply-To: <20260415134705.GG2577880@ziepe.ca>
On Wed, Apr 15, 2026 at 9:47 AM Jason Gunthorpe <jgg@ziepe.ca> wrote:
> On Tue, Apr 14, 2026 at 04:27:58PM -0400, Paul Moore wrote:
> > On Mon, Apr 13, 2026 at 7:19 PM Jason Gunthorpe <jgg@ziepe.ca> wrote:
> > > On Mon, Apr 13, 2026 at 06:36:06PM -0400, Paul Moore wrote:
> > > > On Mon, Apr 13, 2026 at 12:42 PM Jason Gunthorpe <jgg@ziepe.ca> wrote:
> > > > > On Sun, Apr 12, 2026 at 09:38:35PM -0400, Paul Moore wrote:
...
> > > > We've already talked about the first issue, parsing the request, and
> > > > my suggestion was to make the LSM hook call from within the firmware
> > > > (the firmware must have some way to call into the kernel/driver code,
> > > > no?)
> > >
> > > No, that's not workable on so many levels. It is sort of anaologous to
> > > asking the NIC to call the LSM to apply the secmark while sending the
> > > packet.
> >
> > From the LSM's perspective it really doesn't matter who calls the LSM
> > hook as long as the caller can be trusted to handle the access control
> > verdict properly.
>
> The NIC doesn't know anything more than the kernel to call the LSM
> hook. It can't magically generate the label the admin wants to use any
> better than the kernel can.
The NIC presumably knows how to parse the firmware request and extract
whatever security relevant info is needed to pass to the kernel so the
driver can make an access control request.
> Just like you could never get everyone to agree on a fixed set of
> labels for network packets we could never get agreemnt on a fixed set
> of labels for command packets either.
I don't follow you here ... I'm guessing you are talking about secmark
labels? The secmark concept was created not due to any disagreements
on packet labels, but rather the challenges and impacts associated
with packet matching directly in the SELinux code. Secmark was seen
as a more elegant approach to packet matching than the older
"compat_net" SELinux code it replaced. Even with secmark on SELinux,
the packet labels need to be defined in the SELinux policy, the
netfilter code simply assigns these labels to packets using the
netfilter config.
> > > > so that only the firmware would need to parse the request. If we
> > > > wanted to adopt a secmark-esque approach, one could develop a second
> > > > parsing mechanism that would be responsible for assigning a LSM label
> > > > to the request, and then pass the firmware request to the LSM, but I
> > > > do worry a bit about the added complexity associated with keeping the
> > > > parser sync'd with the driver/fw.
> > >
> > > In practice it would be like iptables, the parser would be entirely
> > > programmed by userspace and there is nothing to keep in sync.
> >
> > You've mentioned a few times now that the firmware/request will vary
> > across not only devices, but firmware revisions too,
>
> I never said firmware revisions, part of the requirement is strong ABI
> compatability in these packets.
That was my mistake; it was Leon.
Leon mentioned that different firmware revisions would have different
parameters for a given opcode, and that one would need to inspect
those parameters to properly filter the command. Is that not true, or
am I misreading or misunderstanding Leon's comments?
https://lore.kernel.org/all/20260310175759.GD12611@unreal
> > this implies there will need to be some effort to keep whatever
> > parser you develop (BPF, userspace config, etc.) in sync with the
> > parser built into the firmware. Or am I misunderstanding something?
>
> I would not use the word "sync". It is very similar to deep packet
> inspection, if you want to look inside, say, RPC messages carried
> within HTTP then you have to keep up to date. How onerous that is
> depends on what the admin's labeling goals are.
I'm not sure what to say here, that sounds like a synchronization task
to me, but if you have another term you prefer I'm happy to use that
instead.
> > > > However, even if we solve the parsing problem, I worry we have
> > > > another, closely related issue, of having to categorize all of the
> > > > past, present, and future firmware requests into a set of LSM specific
> > > > actions.
> > >
> > > Why? secmark doesn't have this issue? The classifer would return the
> > > same kind of information as secmark, some user provided label that is
> > > delivered to the LSM policy side.
> >
> > I think there is a misunderstanding in either how secmark works or how
> > the LSMs use secmark labels when enforcing their security policy.
> >
> > The secmark label is set on a packet to represent the network
> > properties of a packet. While the rules governing how a packet's
> > secmark is set and the semantic meaning of that secmark label is going
> > to be LSM and solution specific,
>
> "network properties" are a bit vauge ...
That is one of the main reasons we moved from the old "compat_net"
solution to secmark so that we could leverage all of netfilter's
packet matching capabilities. Once again, if the issue is simply a
matter of phrasing, please let me know what terminology you would
prefer.
> > secmark labels represent the properties of a packet and not the
> > operation, e.g. send/receive/forward/etc., being requested at a
> > given access control point.
>
> Yes, still aligned.
>
> > The access control point itself represents the requested
> > operation. This is possible because the number of networking
> > operations on a given packet is well defined and fairly limited; at a
> > high level the packet is either being sent from the node, received by
> > the node, or is passing through the node.
>
> I think we have the same split, fwctl send/recive analog is also very
> limited.
Sure, but I thought the goal was to enforce access controls on the
firmware requests based on the opcodes/parameters contained within the
firmware request blob/mailbox? Or are you happy with a single
send/receive level of granularity?
> > As I understand the firmware controls being proposed here, encoded
> > within the firmware request blob is the operation being requested.
>
> I am not proposing that kind of interpretation, I want to stay in the
> secmark model.
>
> When the packet blob is sent into the kernel at the uAPI boundary
> (send_msg, send, write, FWCTL_CMD_RPC, etc) that is your access
> control point.
>
> Deep inspection on the packet blob determines the secmark.
... and this would be done by your BPF classifier, yes?
> LSM takes the secmark and determines if the access control point
> accept/rejects.
At this point I think it would be helpful to write out the
subject-access-object triple for an example operation and explain how
an LSM could obtain each component of the access request.
> > While we've discussed possible solutions on how to parse the request
> > blob to determine the operation, we haven't really discussed how to
> > represent the requested operation to the LSMs.
>
> I don't understand this? The secmark example I pulled up is this:
>
> iptables -t mangle -A INPUT -p tcp --dport 80 -j SECMARK --selctx system_u:object_r:httpd_packet_t:s0
>
> The "represent the requested operation" is the string
> "system_u:object_r:httpd_packet_t:s0", which is entirely admin
> defined, right?
No it isn't. The string you've identified is the packet's secmark
label, one of two packet object labels in SELinux (we'll ignore the
other for our discussion). Ignoring the managment controls, the
"requested operation" in SELinux is going to be either send, receive,
forward_in, or forward_out. If we look at some example
subject-op-object triples for a secmark packets, entering or leaving
the system you might see the following:
httpd_t RECV httpd_packet_t
browser_t SEND httpd_packet_t
> > I'm assuming there isn't a well defined set of operations, and like
> > the request format itself, the set of valid operations will vary
> > from device and firmware revision. I hope you can understand both
> > how this differs from secmark and that it is a challenge that really
> > hasn't been addressed in the proposals we've discussed.
>
> I still don't see the difference from iptables. IPSEC, SIP, DNS, HTTP,
> etc are all protocols with the same lack of any commonality.
>
> > At a very high level the access control decision for firmware/device
> > requests depends on whether the LSM wants to allow process A to do B
> > to device C. The identity/credentials associated with process A are
> > easy to understand, we have plenty of examples both inside and outside
> > of the LSM on how to do that. The device identity/attributes
> > associated with device C can be a bit trickier, but once again we have
> > plenty of examples to draw from, and we can even fall back to a
> > generic "kernel" id/attribute if the LSM chooses not to distinguish
> > entities below the userspace/kernel boundary.
>
> I think I would feed that into the classifier as well. Like iptables
> can have a netdev argument to only match against specific devices, we
> can have the same logical thing.
>
> > I think the hardest issue with the firmware request hooks is going
> > to be determining what operation is being requested, the "B",
> > portion of access request tuple. If we can create a well defined
> > set of operations and leave it to the parser to characterize the
> > operation we've potentially got a solution, but if the operation is
> > truly going to be arbitrary then we have a real problem. How do you
> > craft a meaningful access control policy when you don't understand
> > what is being requested?
>
> Same as for networking. Admin understands, admin defines, kernel is
> just a programmable classifier.
Are you able to define all of the firmware request operations at this
point in time? That is my largest concern at this point, and perhaps
the answer is a simple "yes", but I haven't seen it yet.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v2 0/4] Firmware LSM hook
From: Casey Schaufler @ 2026-04-15 21:21 UTC (permalink / raw)
To: Paul Moore
Cc: Jason Gunthorpe, Leon Romanovsky, Roberto Sassu, KP Singh,
Matt Bobrowski, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau,
Eduard Zingerman, Song Liu, Yonghong Song, Stanislav Fomichev,
Hao Luo, Jiri Olsa, Shuah Khan, Saeed Mahameed, Itay Avraham,
Dave Jiang, Jonathan Cameron, bpf, linux-kernel, linux-kselftest,
linux-rdma, Chiara Meiohas, Maher Sanalla, linux-security-module,
Casey Schaufler
In-Reply-To: <CAHC9VhS1sVMGHpO-5Zn0K0w6suTB-i_SwvouDpEmT8sXffsRfg@mail.gmail.com>
On 4/15/2026 2:03 PM, Paul Moore wrote:
> On Tue, Apr 14, 2026 at 6:42 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>> On 4/14/2026 1:44 PM, Paul Moore wrote:
>>> On Tue, Apr 14, 2026 at 4:10 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
>>>> On 4/14/2026 12:09 PM, Paul Moore wrote:
>>>>> On Tue, Apr 14, 2026 at 1:05 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
> ..
>
>> CMW MLS and SELinux MLS can be mapped. They have the same components.
> Yes, one of the fields in a full SELinux label can be an MLS field,
> but that doesn't mean there isn't translation needed. The important
> point is that security label translation, mapping, etc. is necessary,
> possible, and has been proven to work across a variety of systems.
I'm not especially concerned about translation between systems.
The problem at hand is negotiating between LSMs on the same system.
>
>>>> SELinux transmits the MLS component of the security context. Smack passes
>>>> the text of its context.
>>> Arguably the NetLabel/CIPSO interoperability challenge between SELinux
>>> and Smack is due more to differences in how Smack encodes its security
>>> labels into MLS attributes than from any inherent interop limitation.
>> Yes. That is correct. The big issue I see is that SELinux does not represent
>> the entire context in the CIPSO header. Thus, you're up against many SELinux
>> contexts having the same wire representation, where Smack will have a unique
>> on wire for each context ...
> That isn't always true is it? From my understanding of the "cipso2"
> interface an admin could easily map multiple Smack labels to a single
> CIPSO label.
True, but you can't map multiple Smack labels to the same CIPSO label
without introducing ambiguity.
> It's important to remember that if you wanted to utilize CIPSO to
> communicate between SELinux and Smack, the label translation is not
> between SELinux and Smack but rather between SELinux and CIPSO as well
> as between Smack and CIPSO.
>
>>>>> Use of the NetLabel translation cache, e.g. netlbl_cache_add(), would
>>>>> require some additional work to convert over to a lsm_prop instead of
>>>>> a u32/secid, but if you look at the caching code that should be
>>>>> trivial. It might be as simple as adding a lsm_prop to the
>>>>> netlbl_lsm_secattr::attr struct since the cache stores a full secattr
>>>>> and not just a u32/secid.
>>>> Indeed. But with no viable users it seems like a lower priority task.
>>> You need to be very careful about those "viable users" claims ...
>> Today there are no users.
> That you are aware of at the moment. You are also well aware of my
> feelings on this issue and ultimately I'm the one who has to sign off
> on that stuff.
Understood. There are a serious number of considerations that need to
be worked through.
>
>> There are other problems (e.g. mount options) that have yet to be addressed.
> The existence of one problem does not mean another does not exist.
True enough.
^ permalink raw reply
* Re: [PATCH v2 0/4] Firmware LSM hook
From: Paul Moore @ 2026-04-15 21:03 UTC (permalink / raw)
To: Casey Schaufler
Cc: Jason Gunthorpe, Leon Romanovsky, Roberto Sassu, KP Singh,
Matt Bobrowski, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau,
Eduard Zingerman, Song Liu, Yonghong Song, Stanislav Fomichev,
Hao Luo, Jiri Olsa, Shuah Khan, Saeed Mahameed, Itay Avraham,
Dave Jiang, Jonathan Cameron, bpf, linux-kernel, linux-kselftest,
linux-rdma, Chiara Meiohas, Maher Sanalla, linux-security-module
In-Reply-To: <a5fe292b-77c8-4190-8989-1d32cadb5689@schaufler-ca.com>
On Tue, Apr 14, 2026 at 6:42 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
> On 4/14/2026 1:44 PM, Paul Moore wrote:
> > On Tue, Apr 14, 2026 at 4:10 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
> >> On 4/14/2026 12:09 PM, Paul Moore wrote:
> >>> On Tue, Apr 14, 2026 at 1:05 PM Casey Schaufler <casey@schaufler-ca.com> wrote:
...
> CMW MLS and SELinux MLS can be mapped. They have the same components.
Yes, one of the fields in a full SELinux label can be an MLS field,
but that doesn't mean there isn't translation needed. The important
point is that security label translation, mapping, etc. is necessary,
possible, and has been proven to work across a variety of systems.
> >> SELinux transmits the MLS component of the security context. Smack passes
> >> the text of its context.
> > Arguably the NetLabel/CIPSO interoperability challenge between SELinux
> > and Smack is due more to differences in how Smack encodes its security
> > labels into MLS attributes than from any inherent interop limitation.
>
> Yes. That is correct. The big issue I see is that SELinux does not represent
> the entire context in the CIPSO header. Thus, you're up against many SELinux
> contexts having the same wire representation, where Smack will have a unique
> on wire for each context ...
That isn't always true is it? From my understanding of the "cipso2"
interface an admin could easily map multiple Smack labels to a single
CIPSO label.
It's important to remember that if you wanted to utilize CIPSO to
communicate between SELinux and Smack, the label translation is not
between SELinux and Smack but rather between SELinux and CIPSO as well
as between Smack and CIPSO.
> >>> Use of the NetLabel translation cache, e.g. netlbl_cache_add(), would
> >>> require some additional work to convert over to a lsm_prop instead of
> >>> a u32/secid, but if you look at the caching code that should be
> >>> trivial. It might be as simple as adding a lsm_prop to the
> >>> netlbl_lsm_secattr::attr struct since the cache stores a full secattr
> >>> and not just a u32/secid.
> >> Indeed. But with no viable users it seems like a lower priority task.
> > You need to be very careful about those "viable users" claims ...
>
> Today there are no users.
That you are aware of at the moment. You are also well aware of my
feelings on this issue and ultimately I'm the one who has to sign off
on that stuff.
> There are other problems (e.g. mount options) that have yet to be addressed.
The existence of one problem does not mean another does not exist.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v2] trusted-keys: move pr_fmt out of trusted-type.h
From: Marco Felsch @ 2026-04-15 20:50 UTC (permalink / raw)
To: Josh Snyder
Cc: James Bottomley, Jarkko Sakkinen, Mimi Zohar, David Howells,
Ahmad Fatoum, Pengutronix Kernel Team, Paul Moore, James Morris,
Serge E. Hallyn, David Gstir, sigma star Kernel Team,
Srish Srinivasan, Nayna Jain, Sumit Garg, linux-security-module,
linux-integrity, keyrings, linux-kernel
In-Reply-To: <20260415-trusted-key-header-v2-1-5244f9ef0d09@code406.com>
On 26-04-15, Josh Snyder wrote:
> Defining pr_fmt in a widely-included header leaks the "trusted_key: "
> prefix into every translation unit that transitively includes
> <keys/trusted-type.h>. dm-crypt, for example, ends up printing
>
> trusted_key: device-mapper: crypt: dm-10: INTEGRITY AEAD ERROR ...
>
> dm-crypt began including <keys/trusted-type.h> in commit 363880c4eb36
> ("dm crypt: support using trusted keys"), which predates the pr_fmt
> addition, so the regression has been live from the moment the header
> gained its own pr_fmt definition.
>
> Move the pr_fmt definition into the trusted-keys source files that
> actually want the prefix, with specific prefixes for each key type.
>
> Fixes: 5d0682be3189 ("KEYS: trusted: Add generic trusted keys framework")
> Assisted-by: Claude:claude-opus-4-6
> Signed-off-by: Josh Snyder <josh@code406.com>
> ---
> Changes in v2:
> - specific pr_fmt based on trusted key type
> ---
> include/keys/trusted-type.h | 6 ------
> security/keys/trusted-keys/trusted_caam.c | 2 ++
> security/keys/trusted-keys/trusted_core.c | 2 ++
> security/keys/trusted-keys/trusted_dcp.c | 2 ++
> security/keys/trusted-keys/trusted_pkwm.c | 2 ++
> security/keys/trusted-keys/trusted_tpm1.c | 2 ++
> security/keys/trusted-keys/trusted_tpm2.c | 2 ++
You missed the trusted_tee.c, sorry for not spotting this earlier.
Regards,
Marco
> 7 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> index 03527162613f7..54da1f174aeab 100644
> --- a/include/keys/trusted-type.h
> +++ b/include/keys/trusted-type.h
> @@ -11,12 +11,6 @@
> #include <linux/rcupdate.h>
> #include <linux/tpm.h>
>
> -#ifdef pr_fmt
> -#undef pr_fmt
> -#endif
> -
> -#define pr_fmt(fmt) "trusted_key: " fmt
> -
> #define MIN_KEY_SIZE 32
> #define MAX_KEY_SIZE 128
> #if IS_ENABLED(CONFIG_TRUSTED_KEYS_PKWM)
> diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
> index 601943ce0d60f..71c173bb2f727 100644
> --- a/security/keys/trusted-keys/trusted_caam.c
> +++ b/security/keys/trusted-keys/trusted_caam.c
> @@ -4,6 +4,8 @@
> * Copyright 2025 NXP
> */
>
> +#define pr_fmt(fmt) "trusted_key: caam: " fmt
> +
> #include <keys/trusted_caam.h>
> #include <keys/trusted-type.h>
> #include <linux/build_bug.h>
> diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
> index 0b142d941cd2e..159af9dcfc774 100644
> --- a/security/keys/trusted-keys/trusted_core.c
> +++ b/security/keys/trusted-keys/trusted_core.c
> @@ -6,6 +6,8 @@
> * See Documentation/security/keys/trusted-encrypted.rst
> */
>
> +#define pr_fmt(fmt) "trusted_key: " fmt
> +
> #include <keys/user-type.h>
> #include <keys/trusted-type.h>
> #include <keys/trusted_tee.h>
> diff --git a/security/keys/trusted-keys/trusted_dcp.c b/security/keys/trusted-keys/trusted_dcp.c
> index 7b6eb655df0cb..41a23e2f30891 100644
> --- a/security/keys/trusted-keys/trusted_dcp.c
> +++ b/security/keys/trusted-keys/trusted_dcp.c
> @@ -3,6 +3,8 @@
> * Copyright (C) 2021 sigma star gmbh
> */
>
> +#define pr_fmt(fmt) "trusted_key: dcp: " fmt
> +
> #include <crypto/aead.h>
> #include <crypto/aes.h>
> #include <crypto/algapi.h>
> diff --git a/security/keys/trusted-keys/trusted_pkwm.c b/security/keys/trusted-keys/trusted_pkwm.c
> index bf42c6679245a..108db105b639f 100644
> --- a/security/keys/trusted-keys/trusted_pkwm.c
> +++ b/security/keys/trusted-keys/trusted_pkwm.c
> @@ -3,6 +3,8 @@
> * Copyright (C) 2025 IBM Corporation, Srish Srinivasan <ssrish@linux.ibm.com>
> */
>
> +#define pr_fmt(fmt) "trusted_key: pwkm: " fmt
> +
> #include <keys/trusted_pkwm.h>
> #include <keys/trusted-type.h>
> #include <linux/build_bug.h>
> diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
> index 6ea728f1eae6f..207be849796ed 100644
> --- a/security/keys/trusted-keys/trusted_tpm1.c
> +++ b/security/keys/trusted-keys/trusted_tpm1.c
> @@ -6,6 +6,8 @@
> * See Documentation/security/keys/trusted-encrypted.rst
> */
>
> +#define pr_fmt(fmt) "trusted_key: tpm1: " fmt
> +
> #include <crypto/hash_info.h>
> #include <crypto/sha1.h>
> #include <crypto/utils.h>
> diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
> index 6340823f8b53c..2a540b1af0b33 100644
> --- a/security/keys/trusted-keys/trusted_tpm2.c
> +++ b/security/keys/trusted-keys/trusted_tpm2.c
> @@ -4,6 +4,8 @@
> * Copyright (C) 2014 Intel Corporation
> */
>
> +#define pr_fmt(fmt) "trusted_key: tpm2: " fmt
> +
> #include <linux/asn1_encoder.h>
> #include <linux/oid_registry.h>
> #include <linux/string.h>
>
> ---
> base-commit: 66672af7a095d89f082c5327f3b15bc2f93d558e
> change-id: 20260411-trusted-key-header-a544a4f149d2
>
> Best regards,
> --
> Josh
>
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply
* [PATCH v2] trusted-keys: move pr_fmt out of trusted-type.h
From: Josh Snyder @ 2026-04-15 20:40 UTC (permalink / raw)
To: James Bottomley, Jarkko Sakkinen, Mimi Zohar, David Howells,
Ahmad Fatoum, Pengutronix Kernel Team, Paul Moore, James Morris,
Serge E. Hallyn, David Gstir, sigma star Kernel Team,
Srish Srinivasan, Nayna Jain, Sumit Garg
Cc: linux-integrity, keyrings, linux-kernel, linux-security-module,
Josh Snyder
Defining pr_fmt in a widely-included header leaks the "trusted_key: "
prefix into every translation unit that transitively includes
<keys/trusted-type.h>. dm-crypt, for example, ends up printing
trusted_key: device-mapper: crypt: dm-10: INTEGRITY AEAD ERROR ...
dm-crypt began including <keys/trusted-type.h> in commit 363880c4eb36
("dm crypt: support using trusted keys"), which predates the pr_fmt
addition, so the regression has been live from the moment the header
gained its own pr_fmt definition.
Move the pr_fmt definition into the trusted-keys source files that
actually want the prefix, with specific prefixes for each key type.
Fixes: 5d0682be3189 ("KEYS: trusted: Add generic trusted keys framework")
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Josh Snyder <josh@code406.com>
---
Changes in v2:
- specific pr_fmt based on trusted key type
---
| 6 ------
| 2 ++
| 2 ++
| 2 ++
| 2 ++
| 2 ++
| 2 ++
7 files changed, 12 insertions(+), 6 deletions(-)
--git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index 03527162613f7..54da1f174aeab 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -11,12 +11,6 @@
#include <linux/rcupdate.h>
#include <linux/tpm.h>
-#ifdef pr_fmt
-#undef pr_fmt
-#endif
-
-#define pr_fmt(fmt) "trusted_key: " fmt
-
#define MIN_KEY_SIZE 32
#define MAX_KEY_SIZE 128
#if IS_ENABLED(CONFIG_TRUSTED_KEYS_PKWM)
--git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
index 601943ce0d60f..71c173bb2f727 100644
--- a/security/keys/trusted-keys/trusted_caam.c
+++ b/security/keys/trusted-keys/trusted_caam.c
@@ -4,6 +4,8 @@
* Copyright 2025 NXP
*/
+#define pr_fmt(fmt) "trusted_key: caam: " fmt
+
#include <keys/trusted_caam.h>
#include <keys/trusted-type.h>
#include <linux/build_bug.h>
--git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index 0b142d941cd2e..159af9dcfc774 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -6,6 +6,8 @@
* See Documentation/security/keys/trusted-encrypted.rst
*/
+#define pr_fmt(fmt) "trusted_key: " fmt
+
#include <keys/user-type.h>
#include <keys/trusted-type.h>
#include <keys/trusted_tee.h>
--git a/security/keys/trusted-keys/trusted_dcp.c b/security/keys/trusted-keys/trusted_dcp.c
index 7b6eb655df0cb..41a23e2f30891 100644
--- a/security/keys/trusted-keys/trusted_dcp.c
+++ b/security/keys/trusted-keys/trusted_dcp.c
@@ -3,6 +3,8 @@
* Copyright (C) 2021 sigma star gmbh
*/
+#define pr_fmt(fmt) "trusted_key: dcp: " fmt
+
#include <crypto/aead.h>
#include <crypto/aes.h>
#include <crypto/algapi.h>
--git a/security/keys/trusted-keys/trusted_pkwm.c b/security/keys/trusted-keys/trusted_pkwm.c
index bf42c6679245a..108db105b639f 100644
--- a/security/keys/trusted-keys/trusted_pkwm.c
+++ b/security/keys/trusted-keys/trusted_pkwm.c
@@ -3,6 +3,8 @@
* Copyright (C) 2025 IBM Corporation, Srish Srinivasan <ssrish@linux.ibm.com>
*/
+#define pr_fmt(fmt) "trusted_key: pwkm: " fmt
+
#include <keys/trusted_pkwm.h>
#include <keys/trusted-type.h>
#include <linux/build_bug.h>
--git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 6ea728f1eae6f..207be849796ed 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -6,6 +6,8 @@
* See Documentation/security/keys/trusted-encrypted.rst
*/
+#define pr_fmt(fmt) "trusted_key: tpm1: " fmt
+
#include <crypto/hash_info.h>
#include <crypto/sha1.h>
#include <crypto/utils.h>
--git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 6340823f8b53c..2a540b1af0b33 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -4,6 +4,8 @@
* Copyright (C) 2014 Intel Corporation
*/
+#define pr_fmt(fmt) "trusted_key: tpm2: " fmt
+
#include <linux/asn1_encoder.h>
#include <linux/oid_registry.h>
#include <linux/string.h>
---
base-commit: 66672af7a095d89f082c5327f3b15bc2f93d558e
change-id: 20260411-trusted-key-header-a544a4f149d2
Best regards,
--
Josh
^ permalink raw reply related
* Re: [PATCH v2 2/2] integrity: Add support for sigv3 verification using ML-DSA keys
From: Stefan Berger @ 2026-04-15 20:32 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity, linux-security-module
Cc: linux-kernel, roberto.sassu, ebiggers
In-Reply-To: <be3fdb81a322ab96e356e165b737c46f00c12cc3.camel@linux.ibm.com>
On 4/14/26 10:01 PM, Mimi Zohar wrote:
> On Wed, 2026-04-08 at 13:41 -0400, Stefan Berger wrote:
>> Add support for sigv3 signature verification using ML-DSA in pure mode.
>> When a sigv3 signature is verified, first check whether the key to use
>> for verification is an ML-DSA key and therefore uses a hashless signature
>> verification scheme. The hashless signature verification method uses the
>> ima_file_id structure directly for signature verification rather than
>> its digest.
>>
>> Suggested-by: Eric Biggers <ebiggers@kernel.org>
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>>
>
> Thanks, Stefan.
>> ---
>> v2: Set hash_algo in public_key_signature to "none"
>> ---
>> security/integrity/digsig_asymmetric.c | 84 ++++++++++++++++++++++++--
>> 1 file changed, 79 insertions(+), 5 deletions(-)
>>
>> diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
>> index e29ed73f15cd..c80cb2b117a6 100644
>> --- a/security/integrity/digsig_asymmetric.c
>> +++ b/security/integrity/digsig_asymmetric.c
>> @@ -190,17 +190,91 @@ static int calc_file_id_hash(enum evm_ima_xattr_type type,
>> return rc;
>> }
>>
>> +/*
>
> kernel-doc starts with "/**".
I followed the pattern of documentation of a static function that you
just moved:
/*
* calc_file_id_hash - calculate the hash of the ima_file_id struct data
* @type: xattr type [enum evm_ima_xattr_type]
>
>> + * asymmetric_verify_v3_hashless - Use hashless signature verification on sigv3
>> + * @key: The key to use for signature verification
>> + * @pk: The associated public key
>> + * @encoding: The encoding the key type uses
>> + * @sig: The signature
>> + * @siglen: The length of the xattr signature
>> + * @algo: The hash algorithm
>> + * @digest: The file digest
>> + *
>> + * Create an ima_file_id structure and use it for signature verification
>> + * directly. This can be used for ML-DSA in pure mode for example.
>
> Like the comments on 1/2, please add a comment here indicating that all callers
> must verify the signature length (siglen) and the public key (pk) is not NULL,
> before calling asymmetric_verify_v3_hashless(). Also indicate that the caller
> must free the key.
>
>> + */
>> +static int asymmetric_verify_v3_hashless(struct key *key,
>> + const struct public_key *pk,
>> + const char *encoding,
>> + const char *sig, int siglen,
>> + u8 algo,
>> + const u8 *digest)
>> +{
>> + struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
>> + struct ima_file_id file_id = {
>> + .hash_type = hdr->type,
>> + .hash_algorithm = algo,
>> + };
>> + size_t digest_size = hash_digest_size[algo];
>
> Defer initializing the digest_size and .m_size, below, until after checking the
> hash algorithm is valid.
This function is called by asymmetric_verify. asymmetric_verify calls
calc_file_id_hash, which doesn't check algo for valid range, either. I
suppose it's an untrusted value at this point (IMA never checked it's
value for valid range?) an we should check it in asymmetric_verify then
to cover both cases? Or you want to check it individually?
>
>> + struct public_key_signature pks = {
>> + .m = (u8 *)&file_id,
>> + .m_size = sizeof(file_id) - (HASH_MAX_DIGESTSIZE - digest_size),
>> + .s = hdr->sig,
>> + .s_size = siglen - sizeof(*hdr),
>> + .pkey_algo = pk->pkey_algo,
>> + .hash_algo = "none",
>> + .encoding = encoding,
>> + };
>> + int ret;
>> +
>> + if (hdr->type != IMA_VERITY_DIGSIG &&
>> + hdr->type != EVM_IMA_XATTR_DIGSIG &&
>> + hdr->type != EVM_XATTR_PORTABLE_DIGSIG)
>> + return -EINVAL;
>> +
>> + if (pks.s_size != be16_to_cpu(hdr->sig_size))
>> + return -EBADMSG;
>> +
>> + memcpy(file_id.hash, digest, digest_size);
>
> First check the hash algorithm is valid, before using digest_size.
>
>> +
>> + ret = verify_signature(key, &pks);
>> + pr_debug("%s() = %d\n", __func__, ret);
>> + return ret;
>> +}
>> +
>> int asymmetric_verify_v3(struct key *keyring, const char *sig, int siglen,
>> const char *data, int datalen, u8 algo)
>> {
>> struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
>> struct ima_max_digest_data hash;
>> + const struct public_key *pk;
>> + struct key *key;
>> int rc;
>>
>> - rc = calc_file_id_hash(hdr->type, algo, data, &hash);
>> - if (rc)
>> - return -EINVAL;
>> + if (siglen <= sizeof(*hdr))
>> + return -EBADMSG;
>> +
>> + key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
>> + if (IS_ERR(key))
>> + return PTR_ERR(key);
>>
>> - return asymmetric_verify(keyring, sig, siglen, hash.digest,
>> - hash.hdr.length);
>> + pk = asymmetric_key_public_key(key);
>
> Please add a test to check that 'pk' isn't null.
>
>> + if (!strncmp(pk->pkey_algo, "mldsa", 5)) {
>> + rc = asymmetric_verify_v3_hashless(key, pk, "raw",
>> + sig, siglen, algo, data);
>> + } else {
>> + rc = calc_file_id_hash(hdr->type, algo, data, &hash);
>> + if (rc) {
>> + rc = -EINVAL;
>> + goto err_exit;
>> + }
>> +
>> + rc = asymmetric_verify_common(key, pk, sig, siglen, hash.digest,
>> + hash.hdr.length);
>> + }
>> +
>> +err_exit:
>
> Normally a label named 'err*' would be preceded by a return. Here, the label
> "err_exit" is always called, not only when there is an error. Please rename the
> label to something more appropriate - out, cleanup, etc.
Ok, will call it 'out'.
>
>> + key_put(key);
>> +
>> + return rc;
>> }
>
> thanks,
>
> Mimi
>
^ permalink raw reply
* Re: [PATCH v2 1/2] integrity: Refactor asymmetric_verify for reusability
From: Stefan Berger @ 2026-04-15 20:15 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity, linux-security-module
Cc: linux-kernel, roberto.sassu, ebiggers
In-Reply-To: <0375ccecdfb77286dff7f40af5ddbd20f7d6e0fa.camel@linux.ibm.com>
On 4/14/26 10:00 PM, Mimi Zohar wrote:
> On Wed, 2026-04-08 at 13:41 -0400, Stefan Berger wrote:
>> Refactor asymmetric_verify for reusability. Have it call
>> asymmetric_verify_common with the signature verification key and the
>> public_key structure as parameters. sigv3 support for ML-DSA will need to
>> check the public key type first to decide how to do the signature
>> verification and therefore will have these parameters available for
>> calling asymmetric_verify_common.
>>
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>
> Thanks, Stefan.
>
>> ---
>> security/integrity/digsig_asymmetric.c | 42 +++++++++++++++++---------
>> 1 file changed, 28 insertions(+), 14 deletions(-)
>>
>> diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
>> index 6e68ec3becbd..e29ed73f15cd 100644
>> --- a/security/integrity/digsig_asymmetric.c
>> +++ b/security/integrity/digsig_asymmetric.c
>> @@ -79,18 +79,15 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
>> return key;
>> }
>>
>> -int asymmetric_verify(struct key *keyring, const char *sig,
>> - int siglen, const char *data, int datalen)
>> +static int asymmetric_verify_common(const struct key *key,
>> + const struct public_key *pk,
>> + const char *sig, int siglen,
>> + const char *data, int datalen)
>> {
>> - struct public_key_signature pks;
>> struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
>> - const struct public_key *pk;
>> - struct key *key;
>> + struct public_key_signature pks;
>> int ret;
>>
>> - if (siglen <= sizeof(*hdr))
>> - return -EBADMSG;
>> -
>> siglen -= sizeof(*hdr);
>
> Normally kernel-doc is unnecessary for static functions. Here, however, since
> only the caller verifies the signature length, there should be a kernel-doc
> function definition. It should indicate that all callers must verify the
> signature length (siglen) and that the public key (pk) is not NULL, before
> calling asymmetric_verify_common().
Will add.
>
>>
>> if (siglen != be16_to_cpu(hdr->sig_size))
>> @@ -99,15 +96,10 @@ int asymmetric_verify(struct key *keyring, const char *sig,
>> if (hdr->hash_algo >= HASH_ALGO__LAST)
>> return -ENOPKG;
>>
>> - key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
>> - if (IS_ERR(key))
>> - return PTR_ERR(key);
>> -
>> memset(&pks, 0, sizeof(pks));
>>
>> pks.hash_algo = hash_algo_name[hdr->hash_algo];
>>
>> - pk = asymmetric_key_public_key(key);
>> pks.pkey_algo = pk->pkey_algo;
>> if (!strcmp(pk->pkey_algo, "rsa")) {
>> pks.encoding = "pkcs1";
>> @@ -127,11 +119,33 @@ int asymmetric_verify(struct key *keyring, const char *sig,
>> pks.s_size = siglen;
>> ret = verify_signature(key, &pks);
>> out:
>> - key_put(key);
>
> The kernel-doc function definition should also indicate that the caller must
> free the key.
Ok, I will add it. However, symmetric_verify_common cannot free the key
since it is passed as const(!) struct key *key...
>
>> pr_debug("%s() = %d\n", __func__, ret);
>> return ret;
>> }
>>
>> +int asymmetric_verify(struct key *keyring, const char *sig,
>> + int siglen, const char *data, int datalen)
>> +{
>> + struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
>> + const struct public_key *pk;
>> + struct key *key;
>> + int ret;
>> +
>> + if (siglen <= sizeof(*hdr))
>> + return -EBADMSG;
>> +
>> + key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
>> + if (IS_ERR(key))
>> + return PTR_ERR(key);
>> + pk = asymmetric_key_public_key(key);
>
> Please add a test here making sure pk is not null.
As a separate patch for backporting?
Return -ENOKEY in case we hit a NULL pointer?
>
> thanks,
>
> Mimi
>
>> +
>> + ret = asymmetric_verify_common(key, pk, sig, siglen, data, datalen);
>> +
>> + key_put(key);
>> +
>> + return ret;
>> +}
>> +
>> /*
>> * calc_file_id_hash - calculate the hash of the ima_file_id struct data
>> * @type: xattr type [enum evm_ima_xattr_type]
>
^ permalink raw reply
* Re: [PATCH] ima: Use KEXEC_SIG_FORCE for rejecting unsigned kexec images
From: Mimi Zohar @ 2026-04-15 19:22 UTC (permalink / raw)
To: Chi Wang, roberto.sassu, dmitry.kasatkin, eric.snowberg
Cc: paul, jmorris, serge, linux-integrity, linux-security-module,
linux-kernel, Chi Wang
In-Reply-To: <20260415102319.431379-1-wangchi05@163.com>
On Wed, 2026-04-15 at 18:23 +0800, Chi Wang wrote:
> From: Chi Wang <wangchi@kylinos.cn>
>
> Following the split of KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE,
> only KEXEC_SIG_FORCE indicates that unsigned kernel images must be rejected.
> KEXEC_SIG alone enables signature verification but permits unsigned images,
> so it should not trigger the IMA appraisal denial for kexec_load.
>
> Update the condition in ima_load_data() to check for KEXEC_SIG_FORCE
> instead of KEXEC_SIG.
>
> Fixes: 99d5cadfde2b ("kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE")
>
> Signed-off-by: Chi Wang <wangchi@kylinos.cn>
It isn't enough to check whether CONFIG_KEXEC_SIG_FORCE is configured, since it
is possible to require the kexec kernel image to be signed at runtime. Based on
the IMA policy, IMA will call set_kexec_sig_enforced() to require the kexec
kernel image to be signed.
Mimi
> ---
> security/integrity/ima/ima_main.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 1d6229b156fb..ec70e78ab8cd 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -953,7 +953,7 @@ static int ima_load_data(enum kernel_load_data_id id, bool contents)
>
> switch (id) {
> case LOADING_KEXEC_IMAGE:
> - if (IS_ENABLED(CONFIG_KEXEC_SIG)
> + if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)
> && arch_ima_get_secureboot()) {
> pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
> return -EACCES;
> --
> 2.25.1
^ permalink raw reply
* Re: [syzbot] Monthly lsm report (Apr 2026)
From: Jarkko Sakkinen @ 2026-04-15 16:35 UTC (permalink / raw)
To: Paul Moore
Cc: David Howells, linux-kernel, linux-security-module,
syzkaller-bugs, syzbot
In-Reply-To: <CAHC9VhS2AaRwAQw1hNcpuGdFSOL7Li9PavKtU7eW-w8eMOFuKA@mail.gmail.com>
On Tue, Apr 14, 2026 at 10:02:13AM -0400, Paul Moore wrote:
> On Tue, Apr 14, 2026 at 2:48 AM syzbot
> <syzbot+liste5004e02dae137bbd339@syzkaller.appspotmail.com> wrote:
> >
> > Hello lsm maintainers/developers,
> >
> > This is a 31-day syzbot report for the lsm subsystem.
> > All related reports/information can be found at:
> > https://syzkaller.appspot.com/upstream/s/lsm
> >
> > During the period, 0 new issues were detected and 0 were fixed.
> > In total, 3 issues are still open and 45 have already been fixed.
> >
> > Some of the still happening issues:
> >
> > Ref Crashes Repro Title
> > <1> 95 Yes INFO: task hung in process_measurement (3)
> > https://syzkaller.appspot.com/bug?extid=cb9e66807bcb882cd0c5
> > <2> 68 Yes possible deadlock in keyring_clear (3)
> > https://syzkaller.appspot.com/bug?extid=f55b043dacf43776b50c
>
> Jarkko, David,
>
> Do we have a fix for the keyring_clear() issue, or is it not a real problem?
I'm actually doing something to this already: trying to write a
simplified reproducer. But yeah most likely still will take up until
some point next week.
BR, Jarkko
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox