HIGH Introduced in 6.7
bpf PercpuKptr Bypass
CVE-2026-98039
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
01Description
In the Linux kernel, the following vulnerability has been resolved: bpf: Require MEM_PERCPU for percpu kptr stores map_kptr_match_type() treats perm_flags as the set of register type flags that a kptr field permits. Adding MEM_PERCPU to that set for BPF_KPTR_PERCPU does not require the source register to carry it, however. The subset test consequently accepts both a plain bpf_obj_new() allocation and a referenced kernel pointer into a __percpu_kptr map field. Loads from the field are always marked MEM_PERCPU. Consumers then treat the stored value as the cookie returned by bpf_percpu_obj_new(): per-CPU pointer helpers relocate it, and map teardown selects the per-CPU free path. A plain allocation can therefore provide an arbitrary kernel read/write, while a kernel pointer can be relocated into an invalid address or sent through a missing destructor. Require the source MEM_PERCPU flag to match the destination field kind. This preserves valid bpf_percpu_obj_new() stores and rejects both the program-BTF and kernel-BTF variants.
02KernelScan AI Analysis
Risk summary
A BPF verifier type-check flaw allows storing a non-percpu allocation into a percpu kptr map field. When the value is loaded back, it is incorrectly treated as a percpu cookie, enabling arbitrary kernel read/write. Any system that allows BPF program loading is at risk; container hosts and multi-tenant environments face container-escape exposure.
Vulnerability analysis
The BPF verifier does not require that a per-CPU pointer flag on a value matches the per-CPU map field it is stored into. Because the flag is treated as optional, a plain heap allocation or a normal kernel pointer can be written into a per-CPU map field. When the value is later read back, the verifier marks it as a per-CPU pointer, so kernel helpers relocate it as if it were a per-CPU cookie and map teardown frees it through the wrong path. This leads to arbitrary kernel memory read and write. The fix enforces that the per-CPU flag on the source value must match the map field type, blocking invalid stores while allowing legitimate ones. An attacker triggers the flaw by loading a crafted BPF program. This requires CAP_BPF, but on systems that allow unprivileged BPF or delegate BPF tokens to containers, the bug can be reached from inside a user namespace or container.
Lifecycle
03Fix Versions
| Branch | Introduced | Fixed in | Patch commit |
|---|---|---|---|
| 6.12 | 6.7 | 6.12.111 | aaa9cf7707d1 |
| 6.18 | 6.7 | 6.18.53 | 0bdd6121c8dd |
| 7.2 | 6.7 | 7.2.7 | ad4ebae5dbc2 |
| mainline | 6.7 | 7.3-rc2 | 048029ba1c79 |