Thread (27 messages) 27 messages, 4 authors, 2026-05-26

Re: [PATCH bpf-next 00/13] Signed BPF + IPE Policies

From: Paul Moore <paul@paul-moore.com>
Date: 2026-05-22 18:56:48
Also in: bpf

On Thu, May 21, 2026 at 10:32 PM KP Singh [off-list ref] 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/ (local)
[2] Daniel Borkmann, NACK on Hornet v3,
    https://lore.kernel.org/all/798dba24-b5a7-4584-a1f6-793883fe9b5e@iogearbox.net/ (local)
[3] Blaise Boscaccy, Hornet v6 (C-side hash verification rationale),
    https://lore.kernel.org/all/20260429191431.2345448-1-bboscaccy@linux.microsoft.com/ (local)
[4] Paul Moore, push for post-verifier observability,
    https://lore.kernel.org/all/CACYkzJ4+=3owK+ELD9Nw7Rrm-UajxXEw8kVtOTJJ+SNAXpsOpw@mail.gmail.com/ (local)


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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help