[PATCH bpf-next v4 0/9] Verify BPF signed loader at load time
Paul Moore
paul at paul-moore.com
Mon Jul 6 17:13:00 UTC 2026
On Mon, Jul 6, 2026 at 9:56 AM Daniel Borkmann <daniel at iogearbox.net> wrote:
>
> The BPF signing scheme signs a light skeleton's loader program and lets
> the loader vouch for everything else: bpftool bakes the SHA256 of the
> metadata map into the loader's instructions, signs the instructions, and
> the loader compares the (frozen, exclusive) map against that hash from
> within BPF once it runs. The construction is sound as a trusted hash
> chain, but the kernel itself never attests the metadata, and that split
> has been the recurring objection from the LSM / integrity side since the
> scheme was proposed.
>
> This proposal closes both gaps by having the kernel verify the metadata
> at BPF_PROG_LOAD time, before the LSM admission hook and before the
> verifier, /without/ growing the UAPI. A signed loader binds its metadata
> map(s) through the existing fd_array/fd_array_cnt, and exclusive maps
> are already bound to the loader's digest via excl_prog_hash. When a
> signature is present, the kernel collects the exclusive maps from the
> fd_array and appends their frozen contents to the instructions before
> PKCS#7 verification, so the signature covers ...
>
> insns || metadata_0 || metadata_1 || [...]
>
> ... in fd_array order. The in-loader hash check is dropped from the
> gen_loader entirely: generated loaders carry no verification logic
> anymore, and signing or verifying a skeleton becomes an ordinary CMS
> operation over bytes that sit verbatim in the skeleton, reproducible
> offline. A signed program is either BPF_SIG_UNSIGNED or BPF_SIG_VERIFIED
> with nothing in between.
>
> There is no new UAPI, we now have a single signature scheme, no LSM
> code reaching into BPF internals, no new LSM hook, and unsigned loads
> are completely unaffected. It is also less complex since the loader
> does not need to deal with BTF, an extra kfunc, etc, as proposed in
> an earlier series [0]. Tested against full BPF CI which came back
> green. For more details and examples, see the documentation patch in
> this series.
>
> [0] https://lore.kernel.org/bpf/20260522023234.3778588-1-kpsingh@kernel.org/
>
> v3 -> v4:
> - Fix upper limit in MAX_FD_ARRAY_CNT (Anton)
> - Reject !fd_array && attr->fd_array_cnt (Anton)
> - Add bpftool patch wrt ignored return value of EVP_Digest() (sashiko)
> - Fix setting of gen_loader_fixture_init (sashiko)
> - Fix unused map_fd cleanup branch in selftest (bot+bpf-ci)
> - Remove now unused map->excl member and adjust selftests
> - Added more BPF signed_loader corner case selftest coverage
> - Added Paul's Nack wrt bpf_prog_load LSM hook dispute
> - Added patch 2 to move bigger allocations below fd_array
> resolution (Paul)
If you want to squash patch 2/9 and 3/9 together so that one can't
easily merge 3/9 without the vzalloc(program) relocation I'll gladly
drop my NACK on patch 3/9.
> v2 -> v3:
> - Added first commit to cache and work on objects in fd_array
> which was the most recent issue sashiko rightfully complained
> - Added more BPF signed_loader selftest coverage to cover that
> usage of sparse fd_array or map fds gets rejected
> - I left the security_bpf_prog_load as in v2 given preference
> from BPF side over adding new hook
> v1 -> v2:
> - Addressed both sashiko complaints, the TOCTOU bug regarding
> fd_array processing, as well as exclusive map checking to
> only allow array maps. The validation is now moved into the
> verifier before the main verification work happens. This also
> gives the opportunity to utilize the verifier log.
>
> Daniel Borkmann (9):
> bpf: Resolve and cache fd_array objects at load time
> bpf: Move bigger allocations below fd_array resolution
> bpf: Verify signed loader metadata at load time
> libbpf: Drop in-loader metadata check for load-time verification
> bpftool: Check EVP_Digest when computing excl_prog_hash
> bpftool: Cover loader metadata with the program signature
> selftests/bpf: Adjust bpf_map layout in verifier_map_ptr
> selftests/bpf: Verify load-time signed loader metadata
> Documentation/bpf: Add BPF signing and enforcement doc
>
> Documentation/bpf/index.rst | 1 +
> Documentation/bpf/signing.rst | 496 ++++++++
> include/linux/bpf.h | 1 -
> include/linux/bpf_verifier.h | 23 +-
> kernel/bpf/syscall.c | 83 +-
> kernel/bpf/verifier.c | 450 ++++++--
> tools/bpf/bpftool/gen.c | 2 +
> tools/bpf/bpftool/sign.c | 24 +-
> tools/lib/bpf/bpf_gen_internal.h | 1 -
> tools/lib/bpf/gen_loader.c | 76 +-
> tools/lib/bpf/libbpf_internal.h | 1 -
> tools/lib/bpf/skel_internal.h | 31 +-
> .../selftests/bpf/prog_tests/signed_loader.c | 1004 ++++++++++++++---
> .../selftests/bpf/progs/test_signed_loader.c | 9 +-
> .../selftests/bpf/progs/verifier_map_ptr.c | 23 +-
> 15 files changed, 1786 insertions(+), 439 deletions(-)
> create mode 100644 Documentation/bpf/signing.rst
--
paul-moore.com
More information about the Linux-security-module-archive
mailing list