Re: [PATCH bpf-next v4 0/9] Verify BPF signed loader at load time
Paul Moore <[email protected]>
| Newsgroups | org.kernel.vger.linux-security-module,org.kernel.vger.bpf |
|---|---|
| Message-ID | <CAHC9VhQbqxJFBX+3-JiHR7+QqgWsiAAak7J4-q3QykdGqB7g+g@mail.gmail.com> |
On Mon, Jul 6, 2026 at 9:56 AM Daniel Borkmann <[email protected]> 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/[email protected]/ > > 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