From: Paul Moore <paul@paul-moore.com>
To: "Blaise Boscaccy" <bboscaccy@linux.microsoft.com>,
"Blaise Boscaccy" <bboscaccy@linux.microsoft.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"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: Re: [PATCH v5 6/10] security: Hornet LSM
Date: Thu, 23 Apr 2026 14:37:45 -0400 [thread overview]
Message-ID: <7e924e82fbdfb5091f0436fe9ecac2b8@paul-moore.com> (raw)
In-Reply-To: <20260420212653.438685-7-bboscaccy@linux.microsoft.com>
On Apr 20, 2026 Blaise Boscaccy <bboscaccy@linux.microsoft.com> wrote:
>
> This adds the Hornet Linux Security Module which provides enhanced
> signature verification and data validation for eBPF programs. This
> allows users to continue to maintain an invariant that all code
> running inside of the kernel has actually been signed and verified, by
> the kernel.
>
> This effort builds upon the currently excepted upstream solution. It
> further hardens it by providing deterministic, in-kernel checking of
> map hashes to solidify auditing along with preventing TOCTOU attacks
> against lskel map hashes.
>
> Target map hashes are passed in via PKCS#7 signed attributes. Hornet
> determines the extent which the eBFP program is signed and defers to
> other LSMs for policy decisions.
>
> Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
> Nacked-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> ---
> Documentation/admin-guide/LSM/Hornet.rst | 321 +++++++++++++++++++++
> Documentation/admin-guide/LSM/index.rst | 1 +
> MAINTAINERS | 9 +
> include/linux/oid_registry.h | 3 +
> include/uapi/linux/lsm.h | 1 +
> 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 +++++++++++++++++++++++
> 11 files changed, 715 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/admin-guide/LSM/Hornet.rst
> 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
While I think this is looking pretty reasonable, I think Fan had some
feedback which merits a reply. I also spotted some references to the
secondary keyring in the docs which need to be updated (below).
> diff --git a/Documentation/admin-guide/LSM/Hornet.rst b/Documentation/admin-guide/LSM/Hornet.rst
> new file mode 100644
> index 0000000000000..af5e9cd9d83a8
> --- /dev/null
> +++ b/Documentation/admin-guide/LSM/Hornet.rst
> @@ -0,0 +1,321 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +======
> +Hornet
> +======
> +
> +Hornet is a Linux Security Module that provides extensible signature
> +verification for eBPF programs. This is selectable at build-time with
> +``CONFIG_SECURITY_HORNET``.
> +
> +Overview
> +========
> +
> +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.
> +
> +When an eBPF program is loaded via the ``bpf()`` syscall, Hornet
> +verifies a PKCS#7 signature attached to the program instructions. The
> +signature is checked against the kernel's secondary keyring using the
This version now supports using the keyring specified in the bpf_attr
union (presumably for maximum compatibility with KP's signature scheme),
which is good, but the docs need to be updated.
See below, but I would probably make a note that LSMs providing
enforcement of BPF signatures will likely want to check what keyring was
used to verify the signature, e.g. a trusted keyring vs a user supplied
keyring.
> +existing kernel cryptographic infrastructure. In addition to signing the
> +program bytecode, Hornet supports signing SHA-256 hashes of associated
> +BPF maps, enabling integrity verification of map contents at load time
> +and at runtime.
> +
> +After verification, Hornet classifies the program into one of the
> +following integrity states and passes the result to a downstream LSM hook
> +(``bpf_prog_load_post_integrity``), allowing other security modules to
> +make policy decisions based on the verification outcome:
> +
> +``LSM_INT_VERDICT_OK``
> + The program signature and all map hashes verified successfully.
> +
> +``LSM_INT_VERDICT_UNSIGNED``
> + No signature was provided with the program.
> +
> +``LSM_INT_VERDICT_PARTIALSIG``
> + The program signature verified, but the signature did not contain
> + hornet map hash data.
> +
> +``LSM_INT_VERDICT_UNKNOWNKEY``
> + The signing certificate is not trusted in the secondary keyring,
Another secondary keyring mention.
> +``LSM_INT_VERDICT_FAULT``
> + A system error occured during verification.
> +
> +``LSM_INT_VERDICT_UNEXPECTED``
> + An unexpected map hash value was encountered.
> +
> +``LSM_INT_VERDICT_BADSIG``
> + The signature or a map hash failed verification.
> +
> +Hornet itself does not enforce a policy on whether unsigned or partially
> +signed programs should be rejected. It delegates that decision to
> +downstream LSMs via the ``bpf_prog_load_post_integrity`` hook, making it
> +a composable building block in a larger security architecture.
This might be a good place to document that in addition to the verdicts
described above, LSMs providing enforcement should also consider the
keyring used for verification.
> +Known Limitations
> +=================
> +
> +- Hornet requires programs to use :doc:`light skeletons
> + </bpf/libbpf/libbpf_naming_convention>` (lskels) for the signing
> + workflow, as the tooling operates on lskel-generated headers.
> +
> +- A maximum of 64 maps per program can be tracked for hash
> + verification.
> +
> +- Map hash verification requires the maps to be frozen before loading.
> + Maps that are not frozen at load time will cause verification to fail
> + when their hashes are included in the signature.
> +
> +- Hornet relies on the kernel's secondary keyring
> + (``VERIFY_USE_SECONDARY_KEYRING``) for certificate trust. Keys must
> + be provisioned into this keyring before programs can be verified.
... another spot.
> +- The only hashing algorithm available is SHA256 due to it be hardcoded
> + in the bpf subsystem.
...
> +Signature Verification Flow
> +---------------------------
> +
> +The following describes what happens when a userspace program calls
> +``bpf(BPF_PROG_LOAD, ...)`` with a signature attached:
> +
> +1. The ``bpf_prog_load_integrity`` LSM hook is invoked.
> +
> +2. Hornet reads the signature from the userspace buffer specified by
> + ``attr->signature`` (with length ``attr->signature_size``).
> +
> +3. The PKCS#7 signature is verified against the program instructions
> + using ``verify_pkcs7_signature()`` with the kernel's secondary
> + keyring.
I believe this is the last mention of the secondary keyring.
> +4. The PKCS#7 message is parsed and its trust chain is validated via
> + ``validate_pkcs7_trust()``.
> +
> +5. Hornet extracts the authenticated attribute identified by
> + ``OID_hornet_data`` (OID ``2.25.316487325684022475439036912669789383960``)
> + from the PKCS#7 message. This attribute contains an ASN.1-encoded set
> + of map index/hash pairs.
> +
> +6. For each map hash entry, Hornet retrieves the corresponding BPF map
> + via its file descriptor, confirms it is frozen, computes its SHA-256
> + hash, and compares it against the signed hash.
> +
> +7. The resulting integrity verdict is passed to the
> + ``bpf_prog_load_post_integrity`` hook so that downstream LSMs can
> + enforce policy.
--
paul-moore.com
next prev parent reply other threads:[~2026-04-23 18:37 UTC|newest]
Thread overview: 15+ 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-20 21:26 ` [PATCH v5 02/10] crypto: pkcs7: add ability to extract signed attributes by OID Blaise Boscaccy
2026-04-20 21:26 ` [PATCH v5 03/10] crypto: pkcs7: add tests for pkcs7_get_authattr Blaise Boscaccy
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-23 18:37 ` Paul Moore [this message]
2026-04-20 21:26 ` [PATCH v5 07/10] hornet: Introduce gen_sig Blaise Boscaccy
2026-04-21 0:18 ` Fan Wu
2026-04-20 21:26 ` [PATCH v5 08/10] hornet: Add a light skeleton data extractor scripts Blaise Boscaccy
2026-04-20 21:26 ` [PATCH v5 09/10] selftests/hornet: Add a selftest for the Hornet LSM Blaise Boscaccy
2026-04-20 21:26 ` [PATCH v5 10/10] ipe: Add BPF program load policy enforcement via Hornet integration Blaise Boscaccy
2026-04-21 0:27 ` Fan Wu
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=7e924e82fbdfb5091f0436fe9ecac2b8@paul-moore.com \
--to=paul@paul-moore.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=akpm@linux-foundation.org \
--cc=bboscaccy@linux.microsoft.com \
--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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox