Libbpf and Linux Kernel Verifier Compatibility for Unprivileged BPF Loading
0 reputation · 14 Sept 2020, 18:40 UTC
0 reputation · 14 Sept 2020, 18:40 UTC
The goal is to establish whether a given libbpf release can successfully load an unprivileged BPF program that employs CO-RE relocations on a running Linux kernel, taking into account the kernel.unprivileged_bpf_disabled sysctl setting.
Constraints include the kernel version threshold for unprivileged loading (≥5.8 when the sysctl is 0), the verifier tightening introduced in kernels 5.10 and later that may reject programs accepted on earlier releases, the requirement for BTF support (available from kernel 5.4 with CONFIG_DEBUG_INFO_BTF enabled) for CO-RE relocations, the need for clang headers matching the kernel to avoid struct layout mismatches, and the possibility that distribution kernels backport verifier fixes, creating version‑skew uncertainty.
Which minimum kernel version satisfies both the unprivileged loading sysctl and BTF availability for libbpf X.Y?
How does the verifier behavior change between kernel 5.9 and 5.10 affect the acceptability of CO-RE BPF programs compiled with libbpf X.Y?
What steps can be taken to verify that a specific libbpf/kernel/clang combination will allow unprivileged CO-RE program loading without relying on trial and error?
34775 reputation · 15 Sept 2020, 03:35 UTC
To satisfy both the requirement for BPF Type Format (BTF) and the ability to load BPF programs without root privileges (assuming kernel.unprivileged_bpf_disabled = 0), the minimum kernel version is 5.8.
CONFIG_DEBUG_INFO_BTF), which is required for CO-RE (Compile Once – Run Everywhere) relocations.The transition from kernel 5.9 to 5.10 introduced significant tightening of the BPF verifier. While libbpf handles the CO-RE relocations before the program is submitted to the kernel, the resulting bytecode must still pass the verifier's safety checks.
In kernels 5.10 and later, the verifier implements stricter bounds checking and more rigorous pointer arithmetic validation. A CO-RE program compiled with libbpf that successfully loads on 5.9 may be rejected on 5.10 if the relocated offsets or the resulting memory access patterns trigger these new safety constraints. This is not a failure of libbpf's relocation logic, but a change in the kernel's acceptance criteria for the final binary.
To determine if a specific libbpf, kernel, and clang combination will support unprivileged CO-RE loading without trial-and-error, follow these verification steps:
ls /sys/kernel/btf/vmlinux
sysctl kernel.unprivileged_bpf_disabled
Note: A value of 0 is required; 1 or 2 will block unprivileged loading regardless of kernel version.
bpftool to ensure the compiled object contains the necessary CO-RE relocation sections:
bpftool bpf obj dump bpf_program.o
Be aware that many enterprise distributions (e.g., RHEL, Ubuntu LTS) backport verifier fixes and features. A kernel labeled 5.4.x may have verifier behaviors closer to 5.10.x. The only definitive way to confirm compatibility across distributions is to check the specific CONFIG_DEBUG_INFO_BTF status and the active sysctl settings on the target machine.
Use comments to ask for clarification. Post a solution as an answer.
5,940 reputation · 15 Sept 2020, 05:41 UTC
One gap worth filling in the verification workflow: you can probe verifier acceptance directly with bpftool prog loadall your_prog.o /sys/fs/bpf/test, which exercises the exact relocation-plus-verify path without writing a custom loader. Pair it with LIBBPF_DEBUG-level logging (libbpf_set_print in your own loader, or bpftool prog load ... --debug where supported) to see whether a failure came from CO-RE relocation resolution or from the verifier itself — the log output distinguishes these clearly.
Two caveats: first, even with kernel.unprivileged_bpf_disabled=0, many distributions still require CAP_BPF (and sometimes CAP_SYS_ADMIN for certain program types), so check capabilities before blaming the verifier. Second, distro kernels backport verifier patches, so uname -r alone is unreliable — testing on the actual target kernel remains the only definitive check.