CVE-2026-74337: bpf: Fix NMI/tracepoint re-entry deadlock on lru locks
In the Linux kernel, the following vulnerability has been resolved:
bpf: Fix NMI/tracepoint re-entry deadlock on lru locks
NMI and tracepoint BPF programs can re-enter the per-CPU or global LRU lock that bpflrupopfree()/pushfree() already hold on the same CPU, AA-deadlocking. Lockdep reports "inconsistent {INITIAL USE} -> {IN-NMI}" on &l->lock (syzbot c69a0a2c816716f1e0d5) and "possible recursive locking detected" on &locl->lock (syzbot 18b26edb69b2e19f3b33).
Prior trylock and rqspinlock based fixes (see links) were nacked because compromised on reliability.
This patch converts every LRU lock site to rqspinlockt and adds a recovery path for some failure windows to avoid node leaks.
Failure recovery:
- popfree top-level: return NULL; prealloclrupop() already treats that as no-free-element (-ENOMEM).
- Cross-CPU steal: skip the victim's locked locl, try next CPU.
- Post-steal local lock fail: publish stolen node to lockless per-CPU freellist; next pop on this CPU picks it up.
- pushfree fail: mark node pendingfree=1. locallistflush(), locallistpoppending() reclaim the node from pendinglist. bpflrulistshrinkinactive() reclaims the node from inactive list. Nodes from active list are reclaimed by bpflrulistshrink() or after bpflrulistrotateactive() demotes it to the inactive.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Patch bpf: Fix NMI/tracepoint re-entry deadlock on lru locks - Configuration
Update the kernel BPF LRU lock implementation so every LRU lock site uses rqspinlock_t instead of &l->lock/loc_l->lock locking that can trigger inconsistent NMI/tracepoint re-entry deadlocks (as described in the resolved vulnerability).
Linux kernel BPF LRU locking LRU lock type (convert every LRU lock site to rqspinlock_t) = rqspinlock_t - Configuration
Implement/enable the new recovery and reclaim logic: __bpf_lru_list_shrink_inactive() should reclaim nodes from inactive __local_list_flush() and __local_list_pop_pending() should reclaim from pending_list to avoid node leaks during failure windows.
Linux kernel BPF LRU reclaim/recovery paths Inactive/pending list reclaim helpers = use __bpf_lru_list_shrink_inactive() and related inactive/pending reclaim - Compensating control
Apply the described lock and reclaim changes before relying on affected BPF LRU paths, especially those hit by NMI and tracepoint BPF programs, to prevent recursive locking/deadlock conditions reported by lockdep/syzbot.