CVE-2026-98861: fprobe: Use guard(rcu_sched_notrace) and check rcu_is_watching()
In the Linux kernel, the following vulnerability has been resolved:
fprobe: Use guard(rcuschednotrace) and check rcuiswatching()
unregisterfprobe() and unregisterfprobeasync() (used by BPF kprobe-multi) rely on standard RCU grace periods (synchronizercu() and callrcu()) to wait until in-flight fprobe handlers complete before freeing the fprobe.
However, if an fprobe handler executes while RCU is not watching (such as in the idle loop or nohzfull extended quiescent states), standard RCU does not track preemption-disabled sections. Consequently, synchronizercu() does not wait for those executions, which can lead to a use-after-free if the fprobe is freed immediately after unregistration. Ensure handlers exit early when !rcuiswatching().
Furthermore, fprobefgraphentry() and fprobeftraceentry() previously used guard(rcu)() and rcureadlock(), which invoke lockdep on every hit under CONFIGPROVELOCKING. This adds overhead and can cause lockdep recursion if probed functions interact with lockdep.
Since rhltablelookup() and rhlforeachentryrcu() use rcudereferenceallcheck() (which checks rcureadlockanyheld()), holding preemption disabled via rcureadlockschednotrace() is fully valid and sufficient so long as rcuiswatching() is true.
Define and use guard(rcuschednotrace)() across fprobeftraceentry(), fprobefgraphentry(), and fprobereturn(). This eliminates fast-path rcureadlock() and lockdep overhead while guaranteeing safe grace period synchronization.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
Define and use guard(rcu_sched_notrace)() across fprobe_ftrace_entry(), fprobe_fgraph_entry(), and fprobe_return() so standard RCU grace periods wait for in-flight fprobe handlers.
- Compensating control
Make fprobe handlers exit early when !rcu_is_watching(), preventing handler execution while RCU is not watching.
Event History
Frequently Asked Questions
Which systems are most exposed to this issue?
Systems using fprobe, including BPF kprobe-multi users, are relevant. The unsafe condition occurs when an fprobe handler runs while RCU is not watching, such as in the idle loop or during nohz_full extended quiescent states.
What can happen when an affected fprobe is unregistered?
Standard RCU grace periods may fail to wait for an in-flight handler executing with RCU not watching. If the fprobe is then freed immediately, this can result in a use-after-free.
What behavior should the fix introduce?
Fprobe handlers should exit early when rcu_is_watching() is false. The fprobe entry paths should also use rcu_sched_notrace protection rather than the prior RCU locking approach.