CVE-2026-98039: bpf: Require MEM_PERCPU for percpu kptr stores
In the Linux kernel, the following vulnerability has been resolved:
bpf: Require MEMPERCPU for percpu kptr stores
mapkptrmatchtype() treats permflags as the set of register type flags that a kptr field permits. Adding MEMPERCPU to that set for BPFKPTRPERCPU does not require the source register to carry it, however. The subset test consequently accepts both a plain bpfobjnew() allocation and a referenced kernel pointer into a percpukptr map field.
Loads from the field are always marked MEMPERCPU. Consumers then treat the stored value as the cookie returned by bpfpercpuobjnew(): 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 MEMPERCPU flag to match the destination field kind. This preserves valid bpfpercpuobjnew() stores and rejects both the program-BTF and kernel-BTF variants.
Affected Software
Event History
Frequently Asked Questions
What must an attacker be able to do to exploit this issue?
They must be able to load or use a BPF program that stores an invalid pointer type into a __percpu_kptr map field. The vulnerable verifier behavior accepts a plain bpf_obj_new() allocation or a referenced kernel pointer where a per-CPU allocation is required.
What is the potential impact of a successful exploit?
A plain allocation stored in the per-CPU kptr field can lead to arbitrary kernel read and write. A referenced kernel pointer may instead be relocated to an invalid address or processed with an inappropriate or missing destructor during map teardown.
Which stores remain valid after the fix?
Stores of values returned by bpf_percpu_obj_new() remain valid. The fix requires the source register's MEM_PERCPU flag to match the destination field type and rejects non-per-CPU sources for BPF_KPTR_PERCPU fields.