CVE Catalog

CVE-2026-98861

Unknown
Published: Translated: NVD NIST

Summary

A vulnerability was fixed in the Linux kernel's fprobe mechanism where unregister_fprobe() and unregister_fprobe_async() relied on standard RCU grace periods that do not track preemption-disabled sections when RCU is not watching (e.g., in the idle loop or nohz_full extended quiescent states). This could lead to a use-after-free if the fprobe was freed immediately after unregistration. The fix ensures handlers exit early when !rcu_is_watching() and replaces guard(rcu)() and rcu_read_lock() with guard(rcu_sched_notrace)(), eliminating fast-path lockdep overhead.

Risk Assessment

A use-after-free in the kernel can lead to system instability, kernel panic, or potentially privilege escalation by a local attacker. It affects systems using fprobe, including BPF kprobe-multi, especially in nohz_full or CONFIG_PROVE_LOCKING configurations.

Recommendation

Update the Linux kernel to a version containing the fix for CVE-2026-98861. If updating is not possible, consider restricting access to BPF/kprobe mechanisms for untrusted users.

Other vulnerabilities in Linux kernel

See all
Original NVD description (English source)

In the Linux kernel, the following vulnerability has been resolved: fprobe: Use guard(rcu_sched_notrace) and check rcu_is_watching() unregister_fprobe() and unregister_fprobe_async() (used by BPF kprobe-multi) rely on standard RCU grace periods (synchronize_rcu() and call_rcu()) 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 nohz_full extended quiescent states), standard RCU does not track preemption-disabled sections. Consequently, synchronize_rcu() 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 !rcu_is_watching(). Furthermore, fprobe_fgraph_entry() and fprobe_ftrace_entry() previously used guard(rcu)() and rcu_read_lock(), which invoke lockdep on every hit under CONFIG_PROVE_LOCKING. This adds overhead and can cause lockdep recursion if probed functions interact with lockdep. Since rhltable_lookup() and rhl_for_each_entry_rcu() use rcu_dereference_all_check() (which checks rcu_read_lock_any_held()), holding preemption disabled via rcu_read_lock_sched_notrace() is fully valid and sufficient so long as rcu_is_watching() is true. Define and use guard(rcu_sched_notrace)() across fprobe_ftrace_entry(), fprobe_fgraph_entry(), and fprobe_return(). This eliminates fast-path rcu_read_lock() and lockdep overhead while guaranteeing safe grace period synchronization.

Vulnerability data from NVD (NIST) · CISA KEV · EPSS