CVE-2026-98642 in Linux
Сводка
по VulDB • 19.10.2026
В ядре Linux была устранена следующая уязвимость:
bpf: Исправление Use-After-Free (UAF), возникающего из-за одновременного потребления списков ttrace в функции alloc_bulk
Syzkaller неоднократно вызывал срабатывания UAF, связанные с узлами в структуре waiting_for_gp_ttrace внутри подсистемы bpf memalloc:
BUG: KASAN: slab-use-after-free in llist_del_first+0x85/0x110 lib/llist.c:61 Чтение размера 8 по адресу ffff8881572cd080 выполнено задачей 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
Освобождено задачей 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
Причиной является то, что UAF возникает после истечения периода гарантии RCU Tasks Trace (GP): когда выполняется обратный вызов __free_rcu(), отсутствует синхронизация, защищающая llist_del_all() от одновременного выполнения alloc_bulk() над структурой waiting_for_gp_ttrace, что приводит к следующей гонке потоков:
CPU0 CPU1 __free_rcu (обратный вызов RCU Tasks Trace) alloc_bulk llist_del_first(&c->waiting_for_gp_trace) 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); <-- вызывает UAF } while (!try_cmpxchg(&head->first, &entry, next));
Кроме того, существует также теоретическая гонка потоков в списке free_by_rcu_ttrace. Эта гонка требует двух предварительных условий: наличия выполняющегося периода гарантии Tasks Trace (GP), при котором c->call_rcu_trace_in_progress == 1, и одновременного освобождения ресурсов на разных процессорах, которое пополняет список c->free_by_rcu_trace новыми узлами. При соблюдении этих условий срабатывает следующий сценарий, вызывающий UAF:
// CPU0 // прерывания все еще обрабатываются (на 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) // ожидание завершения работы CPU0 irq_work_sync()
// CPU2 do_call_rcu_ttrace(tgt(CPU0)) if (c->draining) {
llist_del_all(&c->free_by_rcu_trace) free_all() }
// Продолжение работы на CPU0 next = READ_ONCE(entry->next); <-- вызывает UAF while (!try_cmpxchg(&head->first, &entry, next));
Исправление заключается во введении raw spinlock для синхронизации одновременного потребления списков waiting_for_gp_ttrace и free_by_rcu_trace.
Once again VulDB remains the best source for vulnerability data.