CVE-2026-98038: bpf: Keep refcount_acquire nullable for borrowed RCU kptrs
In the Linux kernel, the following vulnerability has been resolved:
bpf: Keep refcountacquire nullable for borrowed RCU kptrs
bpfrefcountacquire() is fallible for a borrowed reference because the object may have reached a zero refcount. The verifier therefore keeps KFRETNULL on the return value unless the argument is an owning reference.
An RCU-protected load of a local kptr is marked MEMALLOC, but it only receives NONOWNREF when the pointee contains a graph node. A refcounted object without a graph node consequently looks like an owning reference even though the loaded register has no acquired reference state. If the program drops the last real reference while remaining in the RCU critical section, refcountincnotzero() returns NULL while the verifier treats the result as non-NULL.
Only classify the argument as owning when it is backed by a verifier-tracked reference. This retains the non-NULL return for pointers from bpfobjnew(), bpfkptrxchg(), or an earlier successful acquisition, while requiring a NULL check for borrowed RCU kptrs.
[ kkd: Rewrote commit log ]
Affected Software
Event History
Frequently Asked Questions
Which BPF programs are exposed to this verifier error?
Programs are affected when they perform an RCU-protected load of a local kptr referring to a refcounted object that does not contain a graph node, then use bpf_refcount_acquire(). Such a loaded pointer can be borrowed rather than owned, despite being classified as owning by the vulnerable verifier logic.
What condition triggers the unsafe result?
The issue occurs if the program drops the object's last real reference while still in the RCU critical section. In that case refcount_inc_not_zero() can return NULL, but the verifier may have allowed the program to treat the bpf_refcount_acquire() result as non-NULL.
How can affected BPF code be identified or safely handled?
Review BPF code for bpf_refcount_acquire() calls on pointers obtained through RCU-protected local-kptr loads, especially for object types without graph nodes. Those acquisition results should be treated as nullable and checked before use unless the pointer is backed by a verifier-tracked reference, such as one from bpf_obj_new(), bpf_kptr_xchg(), or a prior successful acquisition.