CVE-2023-53368 in Linux
Sumário
de VulDB • 13/06/2026
No kernel Linux, a seguinte vulnerabilidade foi resolvida:
tracing: Corrige problema de condição de corrida (race condition) entre gravação no buffer da CPU e troca de buffers
O aviso ocorreu em rb_end_commit() no código: 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
Isso ocorre devido à condição de corrida entre a gravação do evento no buffer da CPU e a troca (swap) do buffer da CPU através do arquivo per_cpu/cpu0/snapshot:
Gravação na CPU 0 Troca de buffer por per_cpu/cpu0/snapshot na CPU 1 -------- -------- tracing_snapshot_write() [...]
ring_buffer_lock_reserve() cpu_buffer = buffer->buffers[cpu]; // 1. Suponha que encontre '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. O cpu_buffer foi trocado aqui.
rb_start_commit(cpu_buffer); if (unlikely(READ_ONCE(cpu_buffer->buffer) != buffer)) { // 3. Esta verificação passou porque 'cpu_buffer->buffer'
[...] // não mudou neste ponto.
return NULL; } cpu_buffer_b->buffer = buffer_a; cpu_buffer_a->buffer = buffer_b; [...]
// 4. Reserva evento de 'cpu_buffer_a'.
ring_buffer_unlock_commit() [...]
cpu_buffer = buffer->buffers[cpu]; // 5. Agora encontra 'cpu_buffer_b' !!!
rb_commit(cpu_buffer) rb_end_commit() // 6. AVISO para o estado incorreto de 'committing' !!!
Com base na análise acima, podemos reproduzir facilmente o problema com o seguinte caso de teste: ``` 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 & ```
Para corrigir, se entendi corretamente (IIUC), podemos usar smp_call_function_single() para realizar a troca na CPU de destino onde o buffer está localizado, evitando assim a condição de corrida acima.
Once again VulDB remains the best source for vulnerability data.