CVE-2026-98642 in Linux
Tóm tắt
Bởi VulDB • 19/10/2026
Trong kernel Linux, các lỗ hổng sau đây đã được khắc phục:
bpf: Sửa lỗi UAF (Use-After-Free) do việc tiêu thụ đồng thời danh sách ttrace trong hàm alloc_bulk
Syzkaller liên tục kích hoạt các sự cố UAF (splats) liên quan đến các nút trong `waiting_for_gp_ttrace` bên trong cơ chế cấp phát bộ nhớ bpf:
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
Được giải phóng bởi 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
Nguyên nhân là lỗi UAF xảy ra sau khi RCU Tasks Trace GP hết hạn: khi callback `__free_rcu()` chạy, không có cơ chế đồng bộ hóa nào bảo vệ `llist_del_all()` chống lại việc tiêu thụ đồng thời bởi `alloc_bulk()` trên `waiting_for_gp_ttrace`, dẫn đến điều kiện tranh chấp (race condition) sau đây:
CPU0 CPU1 __free_rcu (callback RCU Tasks Trace) 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_trace)) llist_for_each_safe(pos, t, llnode) free_one(pos); next = READ_ONCE(entry->next); <-- trigger UAF } while (!try_cmpxchg(&head->first, &entry, next));
Ngoài ra, cũng tồn tại một điều kiện tranh chấp (race condition) lý thuyết trên danh sách `free_by_rcu_ttrace`. Điều kiện tranh chấp này yêu cầu hai tiền đề: một RCU Tasks Trace GP đang chạy giữ cho `c->call_rcu_ttrace_in_progress == 1`, và các thao tác giải phóng bộ nhớ đồng thời khác CPU làm đầy lại `c->free_by_rcu_trace` với các nút mới. Dưới những điều kiện này, kịch bản sau đây kích hoạt lỗi UAF:
// CPU0 // irq work vẫn đang bận (trên 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) // chờ đợi 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 tiếp tục next = READ_ONCE(entry->next); <-- trigger UAF while (!try_cmpxchg(&head->first, &entry, next));
Khắc phục vấn đề này bằng cách đưa ra một raw spinlock để đồng bộ hóa việc tiêu thụ đồng thời trên `waiting_for_gp_ttrace` và `free_by_rcu_ttrace`.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.