[PATCH bpf-next 00/13] Signed BPF + IPE Policies
Paul Moore
paul at paul-moore.com
Fri May 22 18:56:36 UTC 2026
On Thu, May 21, 2026 at 10:32 PM KP Singh <kpsingh at kernel.org> wrote:
>
> This series continues the "Signed BPF programs" work and adds
> the missing pieces needed for an LSM to do policy enforcement
> and addresses the concerns raised by the developers of Hornet.
>
> One signing scheme, please.
This is why we tried working with you and Alexei for quite some time,
providing requirements, patches, reviews, and code suggestions.
Unfortunately, our input was not reflected in the signing scheme that
was merged into Linus' tree, so we have had to get creative to meet
our our needs and those of others.
The good news is that the Hornet signatures are compatible with the
existing BPF signing scheme; a Hornet signed BPF program can be
successfully verified by your signing scheme, in current kernels, as
well as the Hornet LSM. Which, while were on the topic of
compatibility, it looks like your proposed changes in this patchset
would break compatibility with existing signed BPF programs, am I
reading the patchset right in this regard?
> BPF does not need a second signing scheme. It needs a policy
> framework that consumes the verdict the existing signing pipeline
> produces. Two parallel signing stacks is harmful UX for Cilium,
> bpftrace, systemd, distros, and everyone shipping signed lskels.
Once again, if one signs BPF programs using the Hornet signing tools
provided in Blaise's patches, the resulting signed BPF can be loaded
and verified using both the existing BPF signature verification code
and Hornet. It is also easy to disable Hornet and/or IPE at kernel
boot using the "lsm=" command line parameter, and of course one can
always tailor the IPE policy to meet specific needs. Although you
surely must be aware of that as your own patchset borrows heavily from
Blaise's original code, albeit without any attribution.
> Hornet has been NACK'd repeatedly by the BPF maintainers [1][2]
> on layering and TOCTOU grounds.
Blaise has recorded Alexei's NACK on the Hornet patchset and addressed
the TOCTOU that Alexei identified. On a related note, Blaise and I
were working with Eric Biggers today - thank you again Eric! - on
identifying some additional issues and I expect Blaise will have
another patch early next week which leverages security_bpf_prog() to
simplify the Hornet code and address some additional issues.
> What this series adds
>
> - prog->aux->sig (verdict + keyring) and prog->aux->is_kernel,
> populated by the syscall path before security_bpf_prog_load
> fires.
> - bpf_loader_verify_metadata kfunc -- the metadata check is now
> kernel C code, not BPF bytecode. The verifier injects the
> calling prog->aux as an implicit argument via KF_IMPLICIT_ARGS.
I think there may have been a misunderstanding regarding the "kernel
C" comments. Our desire was to not have to trust the lskel loader to
do any of the BPF signature verification; perfoming the verification
of both the lskel loader and the original BPF program map in the
native kernel's C code flows, without relying on triggering by the
loader. This greatly simplifies things from a security perspective.
> - Loader-side prog BTF with BPF_PSEUDO_KFUNC_CALL_PROG_BTF so
> the kfunc CALL is reproducible across build hosts and resolved
> at load time.
> - security_bpf_prog_load_post_integrity LSM hook, fired by the
> kfunc on a successful metadata check.
Does a kfunc calling a LSM hook open the door to a potential recursion
issue involving a BPF LSM?
> - IPE properties (bpf_signature, bpf_keyring, bpf_kernel) and
> two ops (BPF_PROG_LOAD, BPF_PROG_LOAD_POST_INTEGRITY).
>
> This series address concerns raised by the Hornet developers:
>
> * The metadata hash check should be in kernel C, not BPF
> bytecode -- Blaise Boscaccy [3]:
>
> The bpf_loader_verify_metadata kfunc moves the hash check from
> inline BPF instructions into kernel C code.
Please see my comments above. While the kfunc is written in C, it is
still reliant on the loader calling that kfunc.
Of course there is still also the usbility issue of not being able to
return an error status to userspace at load time regarding the
verification success of both the loader and the original BPF program
map.
> * LSMs cannot observe the verification result at hook time --
> Paul Moore [4]:
>
> prog->aux->sig.verdict and sig.keyring are populated before any
> LSM hook runs. Furthermore, security_bpf_prog_load_post_integrity
> hook fires after the in-kernel hash check for consumers that want
> to observe or gate the post-integrity transition.
>
> [1] Alexei Starovoitov, NACK on Hornet (TOCTOU + layering),
> https://lore.kernel.org/all/CAADnVQJ1CRvTXBU771KaYzrx-vRaWF+k164DcFOqOsCxmuL+ig@mail.gmail.com/
> [2] Daniel Borkmann, NACK on Hornet v3,
> https://lore.kernel.org/all/798dba24-b5a7-4584-a1f6-793883fe9b5e@iogearbox.net/
> [3] Blaise Boscaccy, Hornet v6 (C-side hash verification rationale),
> https://lore.kernel.org/all/20260429191431.2345448-1-bboscaccy@linux.microsoft.com/
> [4] Paul Moore, push for post-verifier observability,
> https://lore.kernel.org/all/CACYkzJ4+=3owK+ELD9Nw7Rrm-UajxXEw8kVtOTJJ+SNAXpsOpw@mail.gmail.com/
>
>
> KP Singh (13):
> bpf: expose signature verdict to LSMs via bpf_prog_aux
> bpf: include prog BTF in the signed loader signature scope
> bpf, libbpf: load prog BTF in the skel_internal loader
> bpf: add bpf_loader_verify_metadata kfunc
> bpf: compute prog->digest at BPF_PROG_LOAD entry
> bpf: resolve loader-style kfunc CALLs against prog BTF
> libbpf: generate prog BTF for loader programs
> bpftool gen: embed loader prog BTF in the lskel header
> lsm: add bpf_prog_load_post_integrity hook
> bpf: invoke security_bpf_prog_load_post_integrity from the metadata
> kfunc
> ipe: add BPF program signature properties
> ipe: gate post-integrity BPF program loads
> selftests/bpf: add IPE BPF policy integration tests
>
> include/linux/bpf.h | 19 +++
> include/linux/bpf_verifier.h | 6 +
> include/linux/btf.h | 1 +
> include/linux/lsm_hook_defs.h | 1 +
> include/linux/security.h | 6 +
> include/uapi/linux/bpf.h | 5 +
> kernel/bpf/btf.c | 8 +
> kernel/bpf/check_btf.c | 18 +-
> kernel/bpf/helpers.c | 65 ++++++++
> kernel/bpf/syscall.c | 76 ++++++++-
> kernel/bpf/verifier.c | 58 ++++++-
> security/ipe/Kconfig | 14 ++
> security/ipe/audit.c | 13 ++
> security/ipe/eval.c | 57 +++++++
> security/ipe/eval.h | 5 +
> security/ipe/hooks.c | 42 +++++
> security/ipe/hooks.h | 9 +
> security/ipe/ipe.c | 4 +
> security/ipe/policy.h | 11 ++
> security/ipe/policy_parser.c | 20 +++
> security/security.c | 17 ++
> tools/bpf/bpftool/gen.c | 21 +++
> tools/bpf/bpftool/sign.c | 17 +-
> tools/include/uapi/linux/bpf.h | 5 +
> tools/lib/bpf/bpf_gen_internal.h | 2 +
> tools/lib/bpf/gen_loader.c | 127 +++++++++++---
> tools/lib/bpf/libbpf.h | 4 +-
> tools/lib/bpf/skel_internal.h | 67 +++++---
> .../selftests/bpf/test_signed_bpf_ipe.sh | 156 ++++++++++++++++++
> tools/testing/selftests/bpf/vmtest.sh | 4 +-
> 30 files changed, 775 insertions(+), 83 deletions(-)
> create mode 100755 tools/testing/selftests/bpf/test_signed_bpf_ipe.sh
>
> --
> 2.53.0
--
paul-moore.com
More information about the Linux-security-module-archive
mailing list