Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

Vulnerabilidad en Linux (CVE-2026-23342)

Gravedad CVSS v3.1:
MEDIA
Tipo:
CWE-362 Ejecución concurrente utilizando recursos compartidos con una incorrecta sincronización (Condición de carrera)
Fecha de publicación:
25/03/2026
Última modificación:
23/04/2026

Descripción

En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:<br /> <br /> bpf: Corrige condición de carrera en cpumap en PREEMPT_RT<br /> <br /> En kernels PREEMPT_RT, la xdp_bulk_queue (bq) por CPU puede ser accedida concurrentemente por múltiples tareas preemptibles en la misma CPU.<br /> <br /> El código original asume que bq_enqueue() y __cpu_map_flush() se ejecutan atómicamente una con respecto a la otra en la misma CPU, confiando en local_bh_disable() para prevenir la preemption. Sin embargo, en PREEMPT_RT, local_bh_disable() solo llama a migrate_disable() (cuando PREEMPT_RT_NEEDS_BH_LOCK no está configurado) y no deshabilita la preemption, lo que permite que la planificación CFS preempte una tarea durante bq_flush_to_queue(), permitiendo que otra tarea en la misma CPU entre en bq_enqueue() y opere en la misma bq por CPU concurrentemente.<br /> <br /> Esto conduce a varias condiciones de carrera:<br /> <br /> 1. Doble __list_del_clearprev(): después de que bq-&amp;gt;count se reinicia en bq_flush_to_queue(), una tarea preemptora puede llamar a bq_enqueue() -&amp;gt; bq_flush_to_queue() en la misma bq cuando bq-&amp;gt;count alcanza CPU_MAP_BULK_SIZE. Ambas tareas luego llaman a __list_del_clearprev() en el mismo bq-&amp;gt;flush_node, la segunda llamada desreferencia el puntero prev que ya había sido establecido a NULL por la primera.<br /> <br /> 2. Condiciones de carrera de bq-&amp;gt;count y bq-&amp;gt;q[]: bq_enqueue() concurrente puede corromper la cola de paquetes mientras bq_flush_to_queue() la está procesando.<br /> <br /> La condición de carrera entre la tarea A (__cpu_map_flush -&amp;gt; bq_flush_to_queue) y la tarea B (bq_enqueue -&amp;gt; bq_flush_to_queue) en la misma CPU:<br /> <br /> Tarea A (xdp_do_flush) Tarea B (cpu_map_enqueue)<br /> ---------------------- ------------------------<br /> bq_flush_to_queue(bq)<br /> spin_lock(&amp;amp;q-&amp;gt;producer_lock)<br /> /* vaciar bq-&amp;gt;q[] a ptr_ring */<br /> bq-&amp;gt;count = 0<br /> spin_unlock(&amp;amp;q-&amp;gt;producer_lock)<br /> bq_enqueue(rcpu, xdpf)<br /> &amp;lt;-- CFS preempte la Tarea A --&amp;gt; bq-&amp;gt;q[bq-&amp;gt;count++] = xdpf<br /> /* ... más encolamientos hasta llenarse ... */<br /> bq_flush_to_queue(bq)<br /> spin_lock(&amp;amp;q-&amp;gt;producer_lock)<br /> /* vaciar a ptr_ring */<br /> spin_unlock(&amp;amp;q-&amp;gt;producer_lock)<br /> __list_del_clearprev(flush_node)<br /> /* establece flush_node.prev = NULL */<br /> &amp;lt;-- La Tarea A se reanuda --&amp;gt;<br /> __list_del_clearprev(flush_node)<br /> flush_node.prev-&amp;gt;next = ...<br /> /* prev es NULL -&amp;gt; kernel oops */<br /> <br /> Solucione esto añadiendo un local_lock_t a xdp_bulk_queue y adquiriéndolo en bq_enqueue() y __cpu_map_flush(). Estas rutas ya se ejecutan bajo local_bh_disable(), por lo que se usa local_lock_nested_bh() que en sistemas no-RT es una anotación pura sin sobrecarga, y en PREEMPT_RT proporciona un bloqueo de suspensión por CPU que serializa el acceso a la bq.<br /> <br /> Para reproducir, inserte un mdelay(100) entre bq-&amp;gt;count = 0 y __list_del_clearprev() en bq_flush_to_queue(), luego ejecute el reproductor proporcionado por syzkaller.

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.18.1 (incluyendo) 6.18.17 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.19 (incluyendo) 6.19.7 (excluyendo)
cpe:2.3:o:linux:linux_kernel:6.18:-:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc4:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc5:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc6:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:7.0:rc7:*:*:*:*:*:*