All of lore.kernel.org
 help / color / mirror / Atom feed
From: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
To: "Blaise Boscaccy" <bboscaccy@linux.microsoft.com>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Paul Moore" <paul@paul-moore.com>,
	"James Morris" <jmorris@namei.org>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	"Mickaël Salaün" <mic@digikod.net>,
	"Günther Noack" <gnoack@google.com>,
	"Dr. David Alan Gilbert" <linux@treblig.org>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	James.Bottomley@HansenPartnership.com, dhowells@redhat.com,
	"Fan Wu" <wufan@kernel.org>,
	"Ryan Foster" <foster.ryan.r@gmail.com>,
	"Randy Dunlap" <rdunlap@infradead.org>,
	linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
	"Song Liu" <song@kernel.org>
Subject: [PATCH v5 10/10] ipe: Add BPF program load policy enforcement via Hornet integration
Date: Mon, 20 Apr 2026 14:26:42 -0700	[thread overview]
Message-ID: <20260420212653.438685-11-bboscaccy@linux.microsoft.com> (raw)
In-Reply-To: <20260420212653.438685-1-bboscaccy@linux.microsoft.com>

Add support for the bpf_prog_load_post_integrity LSM hook, enabling IPE
to make policy decisions about BPF program loading based on integrity
verdicts provided by the Hornet LSM.

New policy operation:
  op=BPF_PROG_LOAD - Matches BPF program load events

New policy properties:
  bpf_signature=NONE      - No Verdict
  bpf_signature=OK        - Program signature and map hashes verified
  bpf_signature=UNSIGNED  - No signature provided
  bpf_signature=PARTIALSIG - Signature OK but no map hash data
  bpf_signature=UNKNOWNKEY - Cert not trusted
  bpf_signature=UNEXPECTED - An unexpected hash value was encountered
  bpf_signature=FAULT 	   - System error during verification
  bpf_signature=BADSIG    - Signature or map hash verification failed
  bpf_keyring=BUILTIN     - Program was signed using a builtin keyring
  bpf_keyring=SECONDARY   - Program was signed using the secondary keyring
  bpf_keyring=PLATFORM    - Program was signed using the platform keyring
  bpf_kernel=TRUE         - Program originated from kernelspace
  bpf_kernel=FALSE        - Program originated from userspace

These properties map directly to the lsm_integrity_verdict enum values
provided by the Hornet LSM through security_bpf_prog_load_post_integrity.

The feature is gated on CONFIG_IPE_PROP_BPF_SIGNATURE which depends on
CONFIG_SECURITY_HORNET.

Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
---
 Documentation/admin-guide/LSM/ipe.rst | 162 +++++++++++++++++++++++++-
 Documentation/security/ipe.rst        |  39 +++++++
 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 +++++
 11 files changed, 398 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/LSM/ipe.rst b/Documentation/admin-guide/LSM/ipe.rst
index a756d81585317..4dfbf0d325a8a 100644
--- a/Documentation/admin-guide/LSM/ipe.rst
+++ b/Documentation/admin-guide/LSM/ipe.rst
@@ -559,7 +559,8 @@ policy. Two properties are built-into the policy parser: 'op' and 'action'.
 The other properties are used to restrict immutable security properties
 about the files being evaluated. Currently those properties are:
 '``boot_verified``', '``dmverity_signature``', '``dmverity_roothash``',
-'``fsverity_signature``', '``fsverity_digest``'. A description of all
+'``fsverity_signature``', '``fsverity_digest``', '``bpf_signature``',
+'``bpf_keyring``', '``bpf_kernel``'. A description of all
 properties supported by IPE are listed below:
 
 op
@@ -603,6 +604,14 @@ as the first token. IPE supports the following operations:
       Controls loading IMA certificates through the Kconfigs,
       ``CONFIG_IMA_X509_PATH`` and ``CONFIG_EVM_X509_PATH``.
 
+   ``BPF_PROG_LOAD``:
+
+      Pertains to BPF programs being loaded via the ``bpf()`` syscall.
+      This operation is used in conjunction with the ``bpf_signature``,
+      ``bpf_keyring``, and ``bpf_kernel`` properties to control BPF
+      program loading based on integrity verification provided by the
+      Hornet LSM.
+
 action
 ~~~~~~
 
@@ -713,6 +722,105 @@ fsverity_signature
 
       fsverity_signature=(TRUE|FALSE)
 
+bpf_signature
+~~~~~~~~~~~~~
+
+   This property can be utilized for authorization of BPF program loads based
+   on the integrity verdict provided by the Hornet LSM. When a BPF program is
+   loaded, Hornet performs cryptographic verification of the program's PKCS#7
+   signature (if present) and passes an integrity verdict to IPE via the
+   ``security_bpf_prog_load_post_integrity`` hook. IPE can then allow or deny
+   the load based on the verdict.
+
+   This property depends on ``SECURITY_HORNET`` and is controlled by the
+   ``IPE_PROP_BPF_SIGNATURE`` config option.
+   The format of this property is::
+
+      bpf_signature=(NONE|OK|UNSIGNED|PARTIALSIG|UNKNOWNKEY|UNEXPECTED|FAULT|BADSIG)
+
+   The possible values correspond to the integrity verdicts from Hornet:
+
+      ``NONE``
+
+         No integrity verdict was set (default/uninitialized).
+
+      ``OK``
+
+         The BPF program's signature and all map hashes were successfully
+         verified.
+
+      ``UNSIGNED``
+
+         No signature was provided with the BPF program.
+
+      ``PARTIALSIG``
+
+         The program signature was verified, but no authenticated map hash
+         data was present.
+
+      ``UNKNOWNKEY``
+
+         The signing certificate is not trusted by the specified keyring.
+
+      ``UNEXPECTED``
+
+         An unexpected map hash value was encountered during verification.
+
+      ``FAULT``
+
+         A system error occurred during signature verification.
+
+      ``BADSIG``
+
+         The signature or hash verification failed.
+
+bpf_keyring
+~~~~~~~~~~~~
+
+   This property can be utilized for authorization of BPF program loads based
+   on the keyring specified in the ``bpf_attr`` during the ``BPF_PROG_LOAD``
+   syscall. This allows policies to restrict which keyring must be used for
+   signature verification of BPF programs.
+
+   This property shares the ``IPE_PROP_BPF_SIGNATURE`` config option with
+   ``bpf_signature``.
+   The format of this property is::
+
+      bpf_keyring=(BUILTIN|SECONDARY|PLATFORM)
+
+   The possible values correspond to the system keyrings:
+
+      ``BUILTIN``
+
+         The builtin trusted keyring (``.builtin_trusted_keys``), which
+         contains keys embedded at kernel compile time.
+
+      ``SECONDARY``
+
+         The secondary trusted keyring (``.secondary_trusted_keys``), which
+         includes both builtin trusted keys and keys added at runtime.
+
+      ``PLATFORM``
+
+         The platform keyring (``.platform``), which contains keys provided
+         by the platform firmware (e.g. UEFI db keys).
+
+bpf_kernel
+~~~~~~~~~~
+
+   This property can be utilized for authorization of BPF program loads based
+   on whether the load originated from kernel space or user space. The BPF
+   light skeleton infrastructure performs a secondary kernel-originated program
+   load that will not carry a signature. This property allows policies to
+   permit such kernel-originated loads while still requiring signatures for
+   user-space loads.
+
+   This property shares the ``IPE_PROP_BPF_SIGNATURE`` config option with
+   ``bpf_signature``.
+   The format of this property is::
+
+      bpf_kernel=(TRUE|FALSE)
+
 Policy Examples
 ---------------
 
@@ -788,6 +896,58 @@ Allow execution of a specific fs-verity file
 
    op=EXECUTE fsverity_digest=sha256:fd88f2b8824e197f850bf4c5109bea5cf0ee38104f710843bb72da796ba5af9e action=ALLOW
 
+Allow only signed BPF programs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   policy_name=Allow_Signed_BPF policy_version=0.0.0
+   DEFAULT action=ALLOW
+
+   DEFAULT op=BPF_PROG_LOAD action=DENY
+   op=BPF_PROG_LOAD bpf_kernel=TRUE action=ALLOW
+   op=BPF_PROG_LOAD bpf_signature=OK action=ALLOW
+
+This policy allows all other operations but restricts BPF program loading
+to only programs that either originate from kernel space (e.g. light skeleton
+reloads) or have a valid signature verified by the Hornet LSM. Unsigned or
+improperly signed BPF programs from user space will be denied.
+
+Allow signed BPF programs from a specific keyring
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   policy_name=Allow_BPF_Builtin_Keyring policy_version=0.0.0
+   DEFAULT action=ALLOW
+
+   DEFAULT op=BPF_PROG_LOAD action=DENY
+   op=BPF_PROG_LOAD bpf_kernel=TRUE action=ALLOW
+   op=BPF_PROG_LOAD bpf_signature=OK bpf_keyring=BUILTIN action=ALLOW
+
+This policy further restricts BPF program loading to only accept programs
+whose signatures were verified using the builtin trusted keyring. Programs
+signed against the secondary or platform keyrings will be denied, providing
+tighter control over which signing keys are acceptable.
+
+Allow signed BPF programs with relaxed partial signatures
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+   policy_name=Allow_BPF_Partial policy_version=0.0.0
+   DEFAULT action=ALLOW
+
+   DEFAULT op=BPF_PROG_LOAD action=DENY
+   op=BPF_PROG_LOAD bpf_kernel=TRUE action=ALLOW
+   op=BPF_PROG_LOAD bpf_signature=OK action=ALLOW
+   op=BPF_PROG_LOAD bpf_signature=PARTIALSIG action=ALLOW
+
+This policy allows BPF programs that have been fully verified (``OK``) as
+well as programs with a valid program signature but without authenticated
+map hash data (``PARTIALSIG``). This can be useful during development or
+for programs that do not use maps.
+
 Additional Information
 ----------------------
 
diff --git a/Documentation/security/ipe.rst b/Documentation/security/ipe.rst
index 4a7d953abcdc3..de8fcf1dc173d 100644
--- a/Documentation/security/ipe.rst
+++ b/Documentation/security/ipe.rst
@@ -412,6 +412,44 @@ a standard securityfs policy tree::
 
 The policy is stored in the ``->i_private`` data of the MyPolicy inode.
 
+BPF/Hornet Integration
+~~~~~~~~~~~~~~~~~~~~~~
+
+IPE integrates with the Hornet LSM to enforce integrity policies on BPF
+program loading. Hornet performs cryptographic verification of BPF program
+signatures (PKCS#7 with authenticated attributes containing map hashes) and
+provides an integrity verdict to IPE via the
+``security_bpf_prog_load_post_integrity`` hook.
+
+The hook flow is:
+
+  1. User space invokes ``BPF_PROG_LOAD`` via the ``bpf()`` syscall.
+  2. Hornet's ``bpf_prog_load_integrity`` hook calls ``hornet_check_program()``
+     to verify the program's signature and map hashes.
+  3. Hornet calls ``security_bpf_prog_load_post_integrity()`` with the
+     resulting ``lsm_integrity_verdict``.
+  4. IPE evaluates the verdict against the active policy's ``BPF_PROG_LOAD``
+     rules and returns ``-EACCES`` if denied.
+
+Three properties are available for BPF policy rules:
+
+  - ``bpf_signature``: Matches against the integrity verdict (OK, UNSIGNED,
+    BADSIG, etc.)
+  - ``bpf_keyring``: Matches against the keyring specified in ``bpf_attr``
+    (BUILTIN, SECONDARY, PLATFORM)
+  - ``bpf_kernel``: Matches whether the load originated from kernel space
+    (TRUE/FALSE). This is important because the BPF light skeleton
+    infrastructure performs a secondary kernel-originated program load that
+    does not carry a signature.
+
+All three properties are gated on ``CONFIG_IPE_PROP_BPF_SIGNATURE`` which
+depends on ``CONFIG_SECURITY_HORNET``.
+
+The evaluation context (``struct ipe_eval_ctx``) carries three BPF-specific
+fields: ``bpf_verdict`` (the integrity verdict enum), ``bpf_keyring_id``
+(the ``s32`` keyring ID from ``bpf_attr``), and ``bpf_kernel`` (bool
+indicating kernel origin).
+
 Tests
 -----
 
@@ -439,6 +477,7 @@ IPE has KUnit Tests for the policy parser. Recommended kunitconfig::
   CONFIG_IPE_PROP_DM_VERITY_SIGNATURE=y
   CONFIG_IPE_PROP_FS_VERITY=y
   CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG=y
+  CONFIG_IPE_PROP_BPF_SIGNATURE=y
   CONFIG_SECURITY_IPE_KUNIT_TEST=y
 
 In addition, IPE has a python based integration
diff --git a/security/ipe/Kconfig b/security/ipe/Kconfig
index a110a6cd848b7..4c1d46847582b 100644
--- a/security/ipe/Kconfig
+++ b/security/ipe/Kconfig
@@ -95,6 +95,20 @@ config IPE_PROP_FS_VERITY_BUILTIN_SIG
 
 	  if unsure, answer Y.
 
+config IPE_PROP_BPF_SIGNATURE
+	bool "Enable support for Hornet BPF program signature verification"
+	depends on SECURITY_HORNET
+	help
+	  This option enables the 'bpf_signature' and 'bpf_keyring'
+	  properties within IPE policies. The 'bpf_signature' property
+	  allows IPE to make policy decisions based on the integrity
+	  verdict provided by the Hornet LSM when a BPF program is loaded.
+	  Verdicts include OK, UNSIGNED, PARTIALSIG, BADSIG, and others.
+	  The 'bpf_keyring' property allows policies to match against the
+	  keyring specified in bpf_attr (BUILTIN, SECONDARY, PLATFORM).
+
+	  If unsure, answer Y.
+
 endmenu
 
 config SECURITY_IPE_KUNIT_TEST
diff --git a/security/ipe/audit.c b/security/ipe/audit.c
index 3f0deeb549127..251c6ec2f8423 100644
--- a/security/ipe/audit.c
+++ b/security/ipe/audit.c
@@ -41,6 +41,7 @@ static const char *const audit_op_names[__IPE_OP_MAX + 1] = {
 	"KEXEC_INITRAMFS",
 	"POLICY",
 	"X509_CERT",
+	"BPF_PROG_LOAD",
 	"UNKNOWN",
 };
 
@@ -51,6 +52,7 @@ static const char *const audit_hook_names[__IPE_HOOK_MAX] = {
 	"MPROTECT",
 	"KERNEL_READ",
 	"KERNEL_LOAD",
+	"BPF_PROG_LOAD",
 };
 
 static const char *const audit_prop_names[__IPE_PROP_MAX] = {
@@ -62,6 +64,19 @@ static const char *const audit_prop_names[__IPE_PROP_MAX] = {
 	"fsverity_digest=",
 	"fsverity_signature=FALSE",
 	"fsverity_signature=TRUE",
+	"bpf_signature=NONE",
+	"bpf_signature=OK",
+	"bpf_signature=UNSIGNED",
+	"bpf_signature=PARTIALSIG",
+	"bpf_signature=UNKNOWNKEY",
+	"bpf_signature=UNEXPECTED",
+	"bpf_signature=FAULT",
+	"bpf_signature=BADSIG",
+	"bpf_keyring=BUILTIN",
+	"bpf_keyring=SECONDARY",
+	"bpf_keyring=PLATFORM",
+	"bpf_kernel=FALSE",
+	"bpf_kernel=TRUE",
 };
 
 /**
diff --git a/security/ipe/eval.c b/security/ipe/eval.c
index 21439c5be3364..9a6d583fea125 100644
--- a/security/ipe/eval.c
+++ b/security/ipe/eval.c
@@ -11,6 +11,7 @@
 #include <linux/rcupdate.h>
 #include <linux/moduleparam.h>
 #include <linux/fsverity.h>
+#include <linux/verification.h>
 
 #include "ipe.h"
 #include "eval.h"
@@ -265,8 +266,52 @@ static bool evaluate_fsv_sig_true(const struct ipe_eval_ctx *const ctx)
 }
 #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
 
+#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
+/**
+ * evaluate_bpf_sig() - Evaluate @ctx against a bpf_signature property.
+ * @ctx: Supplies a pointer to the context being evaluated.
+ * @expected: The expected lsm_integrity_verdict to match against.
+ *
+ * Return:
+ * * %true	- The current @ctx matches the expected verdict
+ * * %false	- The current @ctx doesn't match the expected verdict
+ */
+static bool evaluate_bpf_sig(const struct ipe_eval_ctx *const ctx,
+			     enum lsm_integrity_verdict expected)
+{
+	return ctx->bpf_verdict == expected;
+}
+#else
+static bool evaluate_bpf_sig(const struct ipe_eval_ctx *const ctx,
+			     enum lsm_integrity_verdict expected)
+{
+	return false;
+}
+#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
+
+#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
+/**
+ * evaluate_bpf_keyring() - Evaluate @ctx against a bpf_keyring property.
+ * @ctx: Supplies a pointer to the context being evaluated.
+ * @expected: The expected keyring_id to match against.
+ *
+ * Return:
+ * * %true	- The current @ctx matches the expected keyring
+ * * %false	- The current @ctx doesn't match the expected keyring
+ */
+static bool evaluate_bpf_keyring(const struct ipe_eval_ctx *const ctx,
+				 s32 expected)
+{
+	return ctx->bpf_keyring_id == expected;
+}
+#else
+static bool evaluate_bpf_keyring(const struct ipe_eval_ctx *const ctx,
+				 s32 expected)
+{
+	return false;
+}
+#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
 /**
- * evaluate_property() - Analyze @ctx against a rule property.
  * @ctx: Supplies a pointer to the context to be evaluated.
  * @p: Supplies a pointer to the property to be evaluated.
  *
@@ -297,6 +342,32 @@ static bool evaluate_property(const struct ipe_eval_ctx *const ctx,
 		return evaluate_fsv_sig_false(ctx);
 	case IPE_PROP_FSV_SIG_TRUE:
 		return evaluate_fsv_sig_true(ctx);
+	case IPE_PROP_BPF_SIG_NONE:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_NONE);
+	case IPE_PROP_BPF_SIG_OK:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_OK);
+	case IPE_PROP_BPF_SIG_UNSIGNED:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_UNSIGNED);
+	case IPE_PROP_BPF_SIG_PARTIALSIG:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_PARTIALSIG);
+	case IPE_PROP_BPF_SIG_UNKNOWNKEY:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_UNKNOWNKEY);
+	case IPE_PROP_BPF_SIG_UNEXPECTED:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_UNEXPECTED);
+	case IPE_PROP_BPF_SIG_FAULT:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_FAULT);
+	case IPE_PROP_BPF_SIG_BADSIG:
+		return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_BADSIG);
+	case IPE_PROP_BPF_KEYRING_BUILTIN:
+		return evaluate_bpf_keyring(ctx, 0);
+	case IPE_PROP_BPF_KEYRING_SECONDARY:
+		return evaluate_bpf_keyring(ctx, (s32)(unsigned long)VERIFY_USE_SECONDARY_KEYRING);
+	case IPE_PROP_BPF_KEYRING_PLATFORM:
+		return evaluate_bpf_keyring(ctx, (s32)(unsigned long)VERIFY_USE_PLATFORM_KEYRING);
+	case IPE_PROP_BPF_KERNEL_FALSE:
+		return !ctx->bpf_kernel;
+	case IPE_PROP_BPF_KERNEL_TRUE:
+		return ctx->bpf_kernel;
 	default:
 		return false;
 	}
diff --git a/security/ipe/eval.h b/security/ipe/eval.h
index fef65a36468cb..1578d83bafc10 100644
--- a/security/ipe/eval.h
+++ b/security/ipe/eval.h
@@ -52,6 +52,11 @@ struct ipe_eval_ctx {
 #ifdef CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG
 	const struct ipe_inode *ipe_inode;
 #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
+#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
+	enum lsm_integrity_verdict bpf_verdict;
+	s32 bpf_keyring_id;
+	bool bpf_kernel;
+#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
 };
 
 enum ipe_match {
diff --git a/security/ipe/hooks.c b/security/ipe/hooks.c
index 0ae54a880405a..03541e5bb7f60 100644
--- a/security/ipe/hooks.c
+++ b/security/ipe/hooks.c
@@ -340,3 +340,40 @@ int ipe_inode_setintegrity(const struct inode *inode,
 	return -EINVAL;
 }
 #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
+
+#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
+/**
+ * ipe_bpf_prog_load_post_integrity() - ipe security hook for BPF program load.
+ * @prog: Supplies the BPF program being loaded.
+ * @attr: Supplies the bpf syscall attributes.
+ * @token: Supplies the BPF token, if any.
+ * @kernel: Whether the call originated from the kernel.
+ * @lsmid: Supplies the LSM ID of the integrity provider.
+ * @verdict: Supplies the integrity verdict from the provider (e.g. Hornet).
+ *
+ * This LSM hook is called after an integrity verification LSM (such as Hornet)
+ * has evaluated a BPF program's cryptographic signature. IPE uses the verdict
+ * to make a policy-based allow/deny decision.
+ *
+ * Return:
+ * * %0		- Success
+ * * %-EACCES	- Did not pass IPE policy
+ */
+int ipe_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)
+{
+	struct ipe_eval_ctx ctx = IPE_EVAL_CTX_INIT;
+
+	ctx.op = IPE_OP_BPF_PROG_LOAD;
+	ctx.hook = IPE_HOOK_BPF_PROG_LOAD;
+	ctx.bpf_verdict = verdict;
+	ctx.bpf_keyring_id = attr->keyring_id;
+	ctx.bpf_kernel = kernel;
+
+	return ipe_evaluate_event(&ctx);
+}
+#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
diff --git a/security/ipe/hooks.h b/security/ipe/hooks.h
index 07db373327402..95b74f7899750 100644
--- a/security/ipe/hooks.h
+++ b/security/ipe/hooks.h
@@ -10,6 +10,7 @@
 #include <linux/security.h>
 #include <linux/blk_types.h>
 #include <linux/fsverity.h>
+#include <linux/bpf.h>
 
 enum ipe_hook_type {
 	IPE_HOOK_BPRM_CHECK = 0,
@@ -18,6 +19,7 @@ enum ipe_hook_type {
 	IPE_HOOK_MPROTECT,
 	IPE_HOOK_KERNEL_READ,
 	IPE_HOOK_KERNEL_LOAD,
+	IPE_HOOK_BPF_PROG_LOAD,
 	__IPE_HOOK_MAX
 };
 
@@ -52,4 +54,13 @@ int ipe_inode_setintegrity(const struct inode *inode, enum lsm_integrity_type ty
 			   const void *value, size_t size);
 #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
 
+#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
+int ipe_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);
+#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
+
 #endif /* _IPE_HOOKS_H */
diff --git a/security/ipe/ipe.c b/security/ipe/ipe.c
index 495bb765de1b8..6502d4ddc641c 100644
--- a/security/ipe/ipe.c
+++ b/security/ipe/ipe.c
@@ -60,6 +60,9 @@ static struct security_hook_list ipe_hooks[] __ro_after_init = {
 #ifdef CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG
 	LSM_HOOK_INIT(inode_setintegrity, ipe_inode_setintegrity),
 #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
+#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
+	LSM_HOOK_INIT(bpf_prog_load_post_integrity, ipe_bpf_prog_load_post_integrity),
+#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
 };
 
 /**
diff --git a/security/ipe/policy.h b/security/ipe/policy.h
index 5bfbdbddeef86..748bea92beb19 100644
--- a/security/ipe/policy.h
+++ b/security/ipe/policy.h
@@ -17,6 +17,7 @@ enum ipe_op_type {
 	IPE_OP_KEXEC_INITRAMFS,
 	IPE_OP_POLICY,
 	IPE_OP_X509,
+	IPE_OP_BPF_PROG_LOAD,
 	__IPE_OP_MAX,
 };
 
@@ -39,6 +40,19 @@ enum ipe_prop_type {
 	IPE_PROP_FSV_DIGEST,
 	IPE_PROP_FSV_SIG_FALSE,
 	IPE_PROP_FSV_SIG_TRUE,
+	IPE_PROP_BPF_SIG_NONE,
+	IPE_PROP_BPF_SIG_OK,
+	IPE_PROP_BPF_SIG_UNSIGNED,
+	IPE_PROP_BPF_SIG_PARTIALSIG,
+	IPE_PROP_BPF_SIG_UNKNOWNKEY,
+	IPE_PROP_BPF_SIG_UNEXPECTED,
+	IPE_PROP_BPF_SIG_FAULT,
+	IPE_PROP_BPF_SIG_BADSIG,
+	IPE_PROP_BPF_KEYRING_BUILTIN,
+	IPE_PROP_BPF_KEYRING_SECONDARY,
+	IPE_PROP_BPF_KEYRING_PLATFORM,
+	IPE_PROP_BPF_KERNEL_FALSE,
+	IPE_PROP_BPF_KERNEL_TRUE,
 	__IPE_PROP_MAX
 };
 
diff --git a/security/ipe/policy_parser.c b/security/ipe/policy_parser.c
index 6fa5bebf84714..71f63de56616b 100644
--- a/security/ipe/policy_parser.c
+++ b/security/ipe/policy_parser.c
@@ -237,6 +237,7 @@ static const match_table_t operation_tokens = {
 	{IPE_OP_KEXEC_INITRAMFS,	"op=KEXEC_INITRAMFS"},
 	{IPE_OP_POLICY,			"op=POLICY"},
 	{IPE_OP_X509,			"op=X509_CERT"},
+	{IPE_OP_BPF_PROG_LOAD,		"op=BPF_PROG_LOAD"},
 	{IPE_OP_INVALID,		NULL}
 };
 
@@ -281,6 +282,19 @@ static const match_table_t property_tokens = {
 	{IPE_PROP_FSV_DIGEST,		"fsverity_digest=%s"},
 	{IPE_PROP_FSV_SIG_FALSE,	"fsverity_signature=FALSE"},
 	{IPE_PROP_FSV_SIG_TRUE,		"fsverity_signature=TRUE"},
+	{IPE_PROP_BPF_SIG_NONE,		"bpf_signature=NONE"},
+	{IPE_PROP_BPF_SIG_OK,		"bpf_signature=OK"},
+	{IPE_PROP_BPF_SIG_UNSIGNED,	"bpf_signature=UNSIGNED"},
+	{IPE_PROP_BPF_SIG_PARTIALSIG,	"bpf_signature=PARTIALSIG"},
+	{IPE_PROP_BPF_SIG_UNKNOWNKEY,	"bpf_signature=UNKNOWNKEY"},
+	{IPE_PROP_BPF_SIG_UNEXPECTED,	"bpf_signature=UNEXPECTED"},
+	{IPE_PROP_BPF_SIG_FAULT,	"bpf_signature=FAULT"},
+	{IPE_PROP_BPF_SIG_BADSIG,	"bpf_signature=BADSIG"},
+	{IPE_PROP_BPF_KEYRING_BUILTIN,	"bpf_keyring=BUILTIN"},
+	{IPE_PROP_BPF_KEYRING_SECONDARY,	"bpf_keyring=SECONDARY"},
+	{IPE_PROP_BPF_KEYRING_PLATFORM,	"bpf_keyring=PLATFORM"},
+	{IPE_PROP_BPF_KERNEL_FALSE,	"bpf_kernel=FALSE"},
+	{IPE_PROP_BPF_KERNEL_TRUE,	"bpf_kernel=TRUE"},
 	{IPE_PROP_INVALID,		NULL}
 };
 
@@ -331,6 +345,19 @@ static int parse_property(char *t, struct ipe_rule *r)
 	case IPE_PROP_DMV_SIG_TRUE:
 	case IPE_PROP_FSV_SIG_FALSE:
 	case IPE_PROP_FSV_SIG_TRUE:
+	case IPE_PROP_BPF_SIG_NONE:
+	case IPE_PROP_BPF_SIG_OK:
+	case IPE_PROP_BPF_SIG_UNSIGNED:
+	case IPE_PROP_BPF_SIG_PARTIALSIG:
+	case IPE_PROP_BPF_SIG_UNKNOWNKEY:
+	case IPE_PROP_BPF_SIG_UNEXPECTED:
+	case IPE_PROP_BPF_SIG_FAULT:
+	case IPE_PROP_BPF_SIG_BADSIG:
+	case IPE_PROP_BPF_KEYRING_BUILTIN:
+	case IPE_PROP_BPF_KEYRING_SECONDARY:
+	case IPE_PROP_BPF_KEYRING_PLATFORM:
+	case IPE_PROP_BPF_KERNEL_FALSE:
+	case IPE_PROP_BPF_KERNEL_TRUE:
 		p->type = token;
 		break;
 	default:
-- 
2.53.0


  parent reply	other threads:[~2026-04-20 21:27 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20 21:26 [PATCH v5 00/10] Reintroduce Hornet LSM Blaise Boscaccy
2026-04-20 21:26 ` [PATCH v5 01/10] crypto: pkcs7: add flag for validated trust on a signed info block Blaise Boscaccy
2026-04-21  1:17   ` sashiko-bot
2026-04-20 21:26 ` [PATCH v5 02/10] crypto: pkcs7: add ability to extract signed attributes by OID Blaise Boscaccy
2026-04-21  1:49   ` sashiko-bot
2026-04-20 21:26 ` [PATCH v5 03/10] crypto: pkcs7: add tests for pkcs7_get_authattr Blaise Boscaccy
2026-04-21  2:06   ` sashiko-bot
2026-04-20 21:26 ` [PATCH v5 04/10] lsm: framework for BPF integrity verification Blaise Boscaccy
2026-04-20 21:26 ` [PATCH v5 05/10] lsm: security: Add additional enum values for bpf integrity checks Blaise Boscaccy
2026-04-20 21:26 ` [PATCH v5 06/10] security: Hornet LSM Blaise Boscaccy
2026-04-21  0:08   ` Fan Wu
2026-04-29 18:34     ` Blaise Boscaccy
2026-04-21  4:29   ` sashiko-bot
2026-04-23 18:37   ` [PATCH v5 6/10] " Paul Moore
2026-04-20 21:26 ` [PATCH v5 07/10] hornet: Introduce gen_sig Blaise Boscaccy
2026-04-21  0:18   ` Fan Wu
2026-04-21  3:03   ` sashiko-bot
2026-04-20 21:26 ` [PATCH v5 08/10] hornet: Add a light skeleton data extractor scripts Blaise Boscaccy
2026-04-21  3:06   ` sashiko-bot
2026-04-20 21:26 ` [PATCH v5 09/10] selftests/hornet: Add a selftest for the Hornet LSM Blaise Boscaccy
2026-04-21  3:04   ` sashiko-bot
2026-04-20 21:26 ` Blaise Boscaccy [this message]
2026-04-21  0:27   ` [PATCH v5 10/10] ipe: Add BPF program load policy enforcement via Hornet integration Fan Wu
2026-04-29 18:35     ` Blaise Boscaccy
2026-04-21  3:23   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260420212653.438685-11-bboscaccy@linux.microsoft.com \
    --to=bboscaccy@linux.microsoft.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=akpm@linux-foundation.org \
    --cc=bpf@vger.kernel.org \
    --cc=corbet@lwn.net \
    --cc=dhowells@redhat.com \
    --cc=foster.ryan.r@gmail.com \
    --cc=gnoack@google.com \
    --cc=jmorris@namei.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux@treblig.org \
    --cc=mic@digikod.net \
    --cc=paul@paul-moore.com \
    --cc=rdunlap@infradead.org \
    --cc=serge@hallyn.com \
    --cc=song@kernel.org \
    --cc=wufan@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.