CVE-2023-53368 in Linux
Tóm tắt
Bởi VulDB • 16/06/2026
Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:
tracing: Sửa lỗi cạnh tranh (race condition) giữa việc ghi vào bộ đệm CPU và thao tác hoán đổi
Cảnh báo xảy ra trong hàm `rb_end_commit()` tại đoạn mã: if (RB_WARN_ON(cpu_buffer, !local_read(&cpu_buffer->committing)))
WARNING: CPU: 0 PID: 139 at kernel/trace/ring_buffer.c:3142 rb_commit+0x402/0x4a0 Call Trace: ring_buffer_unlock_commit+0x42/0x250 trace_buffer_unlock_commit_regs+0x3b/0x250 trace_event_buffer_commit+0xe5/0x440 trace_event_buffer_reserve+0x11c/0x150 trace_event_raw_event_sched_switch+0x23c/0x2c0 __traceiter_sched_switch+0x59/0x80 __schedule+0x72b/0x1580 schedule+0x92/0x120 worker_thread+0xa0/0x6f0
Nguyên nhân là do cạnh tranh giữa việc ghi sự kiện vào bộ đệm CPU và thao tác hoán đổi bộ đệm CPU thông qua tệp per_cpu/cpu0/snapshot:
Ghi trên CPU 0 Hoán đổi bộ đệm bởi per_cpu/cpu0/snapshot trên CPU 1 -------- -------- tracing_snapshot_write() [...]
ring_buffer_lock_reserve() cpu_buffer = buffer->buffers[cpu]; // 1. Giả sử tìm thấy 'cpu_buffer_a';
[...]
rb_reserve_next_event() [...]
ring_buffer_swap_cpu() if (local_read(&cpu_buffer_a->committing)) goto out_dec; if (local_read(&cpu_buffer_b->committing)) goto out_dec; buffer_a->buffers[cpu] = cpu_buffer_b;
buffer_b->buffers[cpu] = cpu_buffer_a;
// 2. cpu_buffer đã được hoán đổi tại đây.
rb_start_commit(cpu_buffer); if (unlikely(READ_ONCE(cpu_buffer->buffer) != buffer)) { // 3. Kiểm tra này vượt qua do 'cpu_buffer->buffer'
[...] // chưa thay đổi ở thời điểm này.
return NULL; } cpu_buffer_b->buffer = buffer_a; cpu_buffer_a->buffer = buffer_b; [...]
// 4. Dành chỗ cho sự kiện từ 'cpu_buffer_a'.
ring_buffer_unlock_commit() [...]
cpu_buffer = buffer->buffers[cpu]; // 5. Bây giờ tìm thấy 'cpu_buffer_b' !!!
rb_commit(cpu_buffer) rb_end_commit() // 6. Cảnh báo (WARN) về trạng thái 'committing' sai !!!
Dựa trên phân tích ở trên, chúng ta có thể dễ dàng tái hiện lỗi bằng testcase sau: ``` bash #!/bin/bash
dmesg -n 7 sysctl -w kernel.panic_on_warn=1 TR=/sys/kernel/tracing echo 7 > ${TR}/buffer_size_kb
echo "sched:sched_switch" > ${TR}/set_event
while [ true ]; do
echo 1 > ${TR}/per_cpu/cpu0/snapshot
done & while [ true ]; do
echo 1 > ${TR}/per_cpu/cpu0/snapshot
done & while [ true ]; do
echo 1 > ${TR}/per_cpu/cpu0/snapshot
done & ```
Để khắc phục, theo hiểu biết của tôi (IIUC), chúng ta có thể sử dụng `smp_call_function_single()` để thực hiện thao tác hoán đổi trên CPU đích nơi bộ đệm được đặt, nhằm tránh cạnh tranh nêu trên.
If you want to get best quality of vulnerability data, you may have to visit VulDB.