All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/5] bpf: Introduce LOADER_LOAD_FD
@ 2026-08-13  0:26 Thiébaud Weksteen
  2026-08-13  0:26 ` [PATCH bpf-next 1/5] fs/kernel_read_file,selinux: Add BPF_LOADER constant Thiébaud Weksteen
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Thiébaud Weksteen @ 2026-08-13  0:26 UTC (permalink / raw)
  To: Paul Moore, Stephen Smalley, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Jeffrey Vander Stoep
  Cc: Thiébaud Weksteen, Ondrej Mosnacek, Eric Suen,
	Blaise Boscaccy, Sid Nayyar, Neill Kapron, Eric Biggers,
	Greg Kroah-Hartman, KP Singh, bpf, selinux, linux-kernel

The bpf subsystem supports a signed-bpf infrastructure to guarantee the
authenticity of programs [1, 2]. While this infrastructure is ideal for
dynamic environments or enterprise deployments where untrusted binaries
are loaded post-boot, it introduces unnecessary complexity for static
platform use cases.

In the Android ecosystem, platform BPF programs reside exclusively on
read-only partitions that are strictly verified at the block level via
dm-verity. Because the kernel has already guaranteed the authenticity of
the underlying file, parsing and validating a secondary signature inside
the BPF subsystem is redundant, complex (because it requires X509 and
PKCS#7 parsing) and necessitates introducing additional signing flows
during build.

Furthermore, relying on signatures forces the kernel to manage a
dedicated public key keyring. In a decentralized ecosystem comprising
various OEMs and SoC vendors, managing these keys specifically for
infrastructure BPF programs presents an operational hurdle.

Thanks to light skeletons, it is possible to embed the loading steps
within a wrapping BPF program (also known as loader). In turns, the
loading of the loader only requires a limited, well-defined number of
steps. This series introduces the bpf command LOADER_LOAD_FD for the
kernel to directly load an ELF file which contains a loader with its
data. By moving the loading within the kernel, the authenticity of the
loader and its content can be guaranteed by existing kernel mechanisms.

Kernel Modules Precedent
------------------------

Verification of authenticity for kernel modules is supported through
multiple options. Deployments may implement PKCS#7 signature validation
or, alternatively, leverage the fact that finit_module(2) retrieves
module data via kernel_read_file().

Android utilizes this latter method for kernel module verification. By
integrating kernel_read_file() with LSM hooks, security policies can
ensure that any loaded module is sourced from a read-only partition
protected by dm-verity, and therefore trusted.

This patch series adopts a similar design for BPF by introducing the
READING_BPF_LOADER constant to the kernel_read_file() enumeration.

The availability of multiple verification paths for kernel modules
reflects the diverse requirements of different environments. Providing
analogous options for the BPF subsystem maintains consistency with this
established kernel precedent.

This proposal again?
--------------------

Similar approaches were proposed in the past [3, 4]. There are
differences that make this proposal worth sharing. Namely, the loading
relies on light skeletons for the heavy lifting. It means that the UAPI
exposed by the kernel is limited: one file descriptor of an ELF with 3
sections; and an opaque context. It also means that the processing done
by the kernel is limited: the majority of the code in this patchset is
doing basic ELF validation and calling the BPF interface that is already
exposed to the rest of the kernel (kern_sys_bpf). 

Design
------

The BPF_LOADER_LOAD_FD command provides a method for the kernel to load
and set up BPF programs and maps directly from an ELF file, guaranteeing
the authenticity of the loaded objects.

It builds upon the light skeleton approach which transfers the loading
logic (i.e., CO-RE, BTF parsing, etc) to a wrapping BPF program (called
loader), generated by libbpf. By relying on these, it is possible to
drastically reduce the expectations on the kernel interface that needs
to be declared and supported.

When loading a light skeleton, libbpf performs 4 actions:
  1. Create a map array.
  2. Populate the map array with the light skeleton’s data.
  3. Load the light skeleton program.
  4. Execute the light skeleton program.
These exact same steps are implemented in LOADER_LOAD_FD.

This new command takes a file descriptor and a context. The file
descriptor is expected to refer to an ELF file which contains 3
sections: __loader.prog, __loader.map and license. These sections are
used as-is in the steps above. The context is passed directly to
BPF_PROG_TEST_RUN. In the current libbpf implementation, that context
contains the file descriptors to the programs and maps that have been
created by the loader (for further processing by userland, such as
pinning). This context is opaque to the kernel in BPF_LOADER_LOAD_FD.

Compared to previous approaches [3] and because this approach relies on
light skeletons, only basic processing is done by the kernel when
loading the programs. CO-RE or BTF are explicitly not supported as these
are handled by the light skeleton loader.

This series also includes the corresponding SELinux changes. Namely, a
new loader_load_fd permission is added to gate the use of the syscall.
It can be used to guarantee that any userspace caller migrates to this
new command instead of the existing BPF_PROG_LOAD. Another permission,
named bpf_load is added to the system class. This permission can be used
to restrict the file allowed to be loaded. Effectively, these
permissions can be used to guarantee that the kernel loads BPF programs
originating from known locations only.

Notes
-----

- There are some limited duplications of the ELF validation between this
  patchset and the existing kernel module loading logic. This can be
  refactored.
- ELF was picked as a container for the loader’s instructions and map.
  There are very few expectations on the ELF, it is mainly a container
  for these opaque bytes.

References
----------

[1] https://lore.kernel.org/bpf/20250921160120.9711-1-kpsingh@kernel.org/
[2] https://lore.kernel.org/bpf/20260708075343.358712-1-daniel@iogearbox.net/
[3] https://lore.kernel.org/bpf/20250109214617.485144-1-bboscaccy@linux.microsoft.com/
[4] https://bpfconf.ebpf.io/bpfconf2024/bpfconf2024_material/LSFMMBPF24_kapron_verified_boot.pdf

Thiébaud Weksteen (5):
  fs/kernel_read_file,selinux: Add BPF_LOADER constant
  bpf: Introduce BPF_LOADER_LOAD_FD command
  selinux: use kernel sid in security_bpf_*
  selinux: Add BPF_LOADER_LOAD_FD syscall permission
  selftests/bpf: add loader_load_fd tests

 include/linux/kernel_read_file.h              |   1 +
 include/uapi/linux/bpf.h                      |   7 +
 kernel/bpf/syscall.c                          | 341 ++++++++++++++++-
 security/selinux/hooks.c                      |  22 +-
 security/selinux/include/classmap.h           |   4 +-
 tools/include/uapi/linux/bpf.h                |   7 +
 tools/testing/selftests/bpf/Makefile          |   8 +-
 tools/testing/selftests/bpf/loader_setup.sh   |  68 ++++
 .../selftests/bpf/prog_tests/loader_load_fd.c | 361 ++++++++++++++++++
 .../testing/selftests/bpf/progs/test_loader.c |  21 +
 10 files changed, 824 insertions(+), 16 deletions(-)
 create mode 100755 tools/testing/selftests/bpf/loader_setup.sh
 create mode 100644 tools/testing/selftests/bpf/prog_tests/loader_load_fd.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_loader.c

-- 
2.55.0.691.gc56d675ccc-goog


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-08-13  1:40 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-13  0:26 [PATCH bpf-next 0/5] bpf: Introduce LOADER_LOAD_FD Thiébaud Weksteen
2026-08-13  0:26 ` [PATCH bpf-next 1/5] fs/kernel_read_file,selinux: Add BPF_LOADER constant Thiébaud Weksteen
2026-08-13  0:36   ` sashiko-bot
2026-08-13  1:25   ` bot+bpf-ci
2026-08-13  0:26 ` [PATCH bpf-next 2/5] bpf: Introduce BPF_LOADER_LOAD_FD command Thiébaud Weksteen
2026-08-13  0:42   ` sashiko-bot
2026-08-13  1:40   ` bot+bpf-ci
2026-08-13  0:26 ` [PATCH bpf-next 3/5] selinux: use kernel sid in security_bpf_* Thiébaud Weksteen
2026-08-13  0:40   ` sashiko-bot
2026-08-13  1:25   ` bot+bpf-ci
2026-08-13  0:26 ` [PATCH bpf-next 4/5] selinux: Add BPF_LOADER_LOAD_FD syscall permission Thiébaud Weksteen
2026-08-13  0:41   ` sashiko-bot
2026-08-13  0:26 ` [PATCH bpf-next 5/5] selftests/bpf: add loader_load_fd tests Thiébaud Weksteen
2026-08-13  0:36   ` sashiko-bot
2026-08-13  1:25   ` bot+bpf-ci

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.