CVE-2026-89988: kprobes: Protect kprobe_blacklist with RCU
In the Linux kernel, the following vulnerability has been resolved:
kprobes: Protect kprobeblacklist with RCU
withinkprobeblacklist() traverses kprobeblacklist without holding kprobemutex. When a module is unloaded, kproberemoveareablacklist() removes blacklist entries and immediately frees them with kfree(). A concurrent call to withinkprobeblacklist() can therefore dereference freed memory.
Furthermore, withinkprobeblacklist() can be called in atomic or non-preemptible contexts where the sleeping kprobemutex cannot be taken.
Protect kprobeblacklist with RCU. Use guard(rcu)() and listforeachentryrcu() for traversal, listaddtailrcu() for insertions, listdelrcu() for deletions, and kfreercu() to reclaim entries safely after a grace period.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
Linux kernel kprobes (kprobe_blacklist)to a version that resolves this vulnerability.Patch kprobes: Protect kprobe_blacklist with RCU - Configuration
Apply the kernel fix that protects kprobe_blacklist with RCU: use guard(rcu)() in within_kprobe_blacklist(), traverse with list_for_each_entry_rcu(), insert with list_add_tail_rcu(), delete with list_del_rcu(), and reclaim memory with kfree_rcu() after module unload via kprobe_remove_area_blacklist() (avoid immediate kfree()).
Linux kernel kprobes kprobe_blacklist synchronization = Protected with RCU; use guard(rcu)(), list_for_each_entry_rcu(), list_add_tail_rcu(), and list_del_rcu(); reclaim with kfree_rcu()
Event History
Frequently Asked Questions
What conditions are required for this issue to occur?
A module unload must remove kprobe blacklist entries while another execution concurrently calls within_kprobe_blacklist(). The concurrent traversal can then access an entry that was freed immediately after removal.
Why is locking with kprobe_mutex not a viable protection for this path?
within_kprobe_blacklist() may run in atomic or non-preemptible contexts. Because kprobe_mutex can sleep, it cannot safely be acquired in those contexts.
What does the resolved implementation change to prevent the race?
Blacklist traversal and updates are protected with RCU, including RCU list operations and deferred freeing with kfree_rcu(). This keeps removed entries valid until an RCU grace period has elapsed, preventing concurrent readers from dereferencing freed memory.