CVE-2026-98642 in Linux
Summary
by MITRE • 10/18/2026
In the Linux kernel, the following vulnerability has been resolved:
bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk
Syzkaller repeatedly triggered UAF splats related to nodes in waiting_for_gp_ttrace within the bpf memalloc:
BUG: KASAN: slab-use-after-free in llist_del_first+0x85/0x110 lib/llist.c:61 Read of size 8 at addr ffff8881572cd080 by task syz.4.470/5112 ... llist_del_first+0x85/0x110 lib/llist.c:61 alloc_bulk+0x193/0x460 kernel/bpf/memalloc.c:229 bpf_mem_refill+0x386/0x560 kernel/bpf/memalloc.c:436
Freed by task 14: ... __free_rcu kernel/bpf/memalloc.c:281 [inline]
__free_rcu_tasks_trace+0x48/0xd0 kernel/bpf/memalloc.c:291 rcu_tasks_invoke_cbs+0x1ec/0x3e0 kernel/rcu/tasks.h:571 rcu_tasks_one_gp+0x13d/0x220 kernel/rcu/tasks.h:621 rcu_tasks_kthread+0xf3/0x120 kernel/rcu/tasks.h:651
The reason is that the UAF occurs after the RCU Tasks Trace GP expires: when the __free_rcu() callback runs, there is no synchronization protecting llist_del_all() against concurrent alloc_bulk() operating on waiting_for_gp_ttrace, leading to the race condition below:
CPU0 CPU1 __free_rcu (RCU Tasks Trace callback) alloc_bulk llist_del_first(&c->waiting_for_gp_ttrace) entry = smp_load_acquire(&head->first); do {
if (entry == NULL) return NULL; free_all(llist_del_all(&c->waiting_for_gp_ttrace)) llist_for_each_safe(pos, t, llnode) free_one(pos); next = READ_ONCE(entry->next); <-- trigger UAF } while (!try_cmpxchg(&head->first, &entry, next));
In addition, there is also a theoretical race condition on the free_by_rcu_ttrace list. This race requires two preconditions: an in-flight Tasks Trace GP keeping c->call_rcu_ttrace_in_progress == 1, and concurrent cross-CPU frees repopulating c->free_by_rcu_ttrace with new nodes. Under these conditions, the following scenario triggers UAF:
// CPU0 // irq work is still busy (on PREEMPT_RT) alloc_bulk() llist_del_first(&c->free_by_rcu_ttrace) entry = smp_load_acquire(&head->first); do {
if (entry == NULL) return NULL;
// CPU1 bpf_mem_alloc_destroy() WRITE_ONCE(c->draining, true) // wait for CPU0 irq_work_sync()
// CPU2 do_call_rcu_ttrace(tgt(CPU0)) if (c->draining) {
llist_del_all(&c->free_by_rcu_ttrace) free_all() }
// CPU0 continue next = READ_ONCE(entry->next); <-- trigger UAF while (!try_cmpxchg(&head->first, &entry, next));
Fix this by introducing a raw spinlock to synchronize the concurrent consumption on waiting_for_gp_ttrace and free_by_rcu_ttrace.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 10/18/2026
The Linux kernel BPF subsystem contains a critical use-after-free vulnerability arising from race conditions during the concurrent management of memory allocation lists within the bpf_memalloc module. This flaw specifically affects the handling of nodes in the waiting_for_gp_ttrace and free_by_rcu_ttrace linked lists, which are utilized to manage deferred freeing operations associated with RCU Tasks Trace grace periods. The vulnerability is triggered when multiple CPU cores attempt to consume or modify these lock-free linked list structures simultaneously without adequate synchronization primitives. Syzkaller fuzzing efforts have repeatedly exposed this issue by generating splashes indicating slab-use-after-free errors within the llist_del_first function, which is called during bulk allocation attempts via alloc_bulk. The root cause lies in the lack of mutual exclusion when an RCU Tasks Trace grace period expires and its associated callback runs concurrently with a thread attempting to allocate memory from these lists.
The technical mechanism of this vulnerability involves a classic time-of-check-to-time-of-use race condition on lock-free data structures. When CPU0 executes alloc_bulk, it attempts to remove the first element from the waiting_for_gp_ttrace list using llist_del_first. Simultaneously, if an RCU Tasks Trace grace period expires on another core or context, the __free_rcu callback is invoked to free these nodes. Without proper synchronization, CPU1 may invoke llist_del_all to drain and free all entries in the list while CPU0 is still iterating through them using a loop that reads the next pointer of an entry before successfully updating the head with try_cmpxchg. This results in CPU0 accessing memory that has already been freed by the RCU callback, leading to undefined behavior, potential kernel panics, or arbitrary code execution if the freed memory is reallocated and manipulated maliciously. The vulnerability exploits the assumption that lock-free operations are atomic across all concurrent accesses, which does not hold when one side of the operation involves a deferred free triggered by an external grace period mechanism.
A secondary theoretical race condition exists within the free_by_rcu_ttrace list handling path. This scenario requires specific preconditions where an in-flight Tasks Trace grace period keeps the call_rcu_ttrace_in_progress flag set to true, while concurrent cross-CPU frees repopulate the free_by_rcu_ttrace list with new nodes. In this state, if CPU0 is engaged in alloc_bulk and has loaded a pointer from the head of the list but not yet completed its update operation, another core might trigger bpf_mem_alloc_destroy due to draining conditions. This destruction process waits for interrupt work synchronization before calling llist_del_all on the free_by_rcu_ttrace list. If this deletion occurs while CPU0 is still processing the entry it previously loaded, CPU0 will subsequently attempt to read the next pointer of a node that has been freed by the concurrent destroy operation. This specific sequence highlights how complex interactions between memory allocation paths and RCU teardown procedures can create subtle concurrency bugs in high-performance kernel subsystems like BPF.
The operational impact of this vulnerability is significant for systems relying on eBPF programs, particularly those with heavy dynamic loading or unloading activity under multi-core workloads. A successful exploitation could allow a local user to crash the system by triggering a null pointer dereference or general protection fault when accessing freed memory structures. More severely, if an attacker can control the contents of the reallocated memory region before it is accessed again, they might achieve arbitrary read/write primitives within kernel space. This undermines the integrity and availability guarantees provided by the Linux kernel security model. Given that BPF programs are often used in network filtering and observability tools running with high privileges, such a vulnerability poses a substantial risk to system stability and data confidentiality on production servers and cloud infrastructure instances where eBPF is heavily utilized for performance monitoring and traffic control.
To mitigate this vulnerability, the Linux kernel maintainers have implemented a fix by introducing a raw spinlock to synchronize access to both the waiting_for_gp_ttrace and free_by_rcu_ttrace lists. This change ensures that concurrent consumption of these lists is mutually exclusive, preventing the race condition where one thread frees nodes while another iterates over them. The addition of explicit locking primitives overrides the previous reliance on lock-free algorithms for these specific critical sections, thereby guaranteeing data consistency during memory allocation and deallocation cycles. System administrators should ensure their kernels are updated to include this patch. For environments unable to immediately update, restricting unprivileged eBPF program loading via BPF_PROG_LOAD restrictions or disabling dynamic module loading can reduce the attack surface, although applying the kernel fix remains the only definitive resolution.
From a classification perspective, this vulnerability aligns with CWE-416 Use After Free and CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization Race Condition. The exploitation technique involves manipulating shared memory structures without proper synchronization, which is characteristic of race condition vulnerabilities in kernel space. In the context of the MITRE ATT&CK framework for enterprise security, this flaw relates to techniques involving privilege escalation through local exploits or denial of service via system instability. Understanding these classifications helps security teams prioritize patching efforts and monitor for indicators of compromise that might indicate attempts to exploit similar concurrency issues in other subsystems. The fix exemplifies best practices in kernel development by prioritizing correctness over performance optimizations when concurrent access patterns are complex and prone to subtle timing errors.