How eBPF Program is Executed
An eBPF program can be interpreted as bytecode or compiled into native code and loaded into the kernel. An eBPF program, whether interpreted or compiled, should be verified by the eBPF verifier.
The CONFIG_JIT_ALWAYS_ON config option decides whether an eBPF program is compiled into native code. Distributions enable this configuration by default, yet defconfig disables it by default.
JIT brings performance benefits, yet requires much engineering work.
Required Privilege
In Linux v5.8 and earlier versions, certain eBPF programs require CAP_BPF, such as socket filters.
In Linux v6 and later versions, eBPF programs can be loaded by normal users, but they require a special config option.
eBPF Engineering Issue
- The eBPF verifier kills normal programs.
- eBPF verifier cannot detect out-of-bound write.
- eBPF debugging is not user friendly.
- Optimization may affect the eBPF verifier.
- Helper functions have different behavior
BPF_read_user()helper function issue on ARM (v7.1 and above)- caused by PAN feature
- Issue Track
- Patch Mail
eBPF Security Issue
If a data pointer pointing to an eBPF program is manipulated and redirected to a vulnerable eBPF program, the interpreter can interpret eBPF shellcode. Such shellcode can bypass the eBPF verifier.
When an eBPF tail call loads the malicious pointer, shellcode can be interpreted.