Vulnerabilidad en Linux (CVE-2026-23394)
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
25/03/2026
Última modificación:
25/03/2026
Descripción
En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:<br />
<br />
af_unix: Abandonar la recolección de basura (GC) si MSG_PEEK intervino.<br />
<br />
Igor Ushakov informó que la recolección de basura (GC) purgó la cola de recepción de un socket activo debido a una condición de carrera con MSG_PEEK con una buena reproducción.<br />
<br />
Este es exactamente el mismo problema previamente solucionado por el commit cbcf01128d0a (&#39;af_unix: corregir recolección de basura vs MSG_PEEK&#39;).<br />
<br />
Después de que la recolección de basura (GC) fue reemplazada por el algoritmo actual, el commit citado eliminó la &#39;danza de bloqueo&#39; en unix_peek_fds() y reintrodujo el mismo problema.<br />
<br />
El problema es que MSG_PEEK incrementa un contador de referencias de archivo sin interactuar con la recolección de basura (GC).<br />
<br />
Considere un SCC que contiene sk-A y sk-B, donde sk-A está close()d (cerrado) pero puede ser recv()ed (recibido) a través de sk-B.<br />
<br />
Lo malo sucede si sk-A es recv()ed (recibido) con MSG_PEEK desde sk-B y sk-B está close()d (cerrado) mientras la recolección de basura (GC) está verificando unix_vertex_dead() para sk-A y sk-B.<br />
<br />
Hilo de GC Hilo de usuario<br />
--------- -----------<br />
unix_vertex_dead(sk-A)<br />
-&gt; true &lt;------.<br />
\<br />
`------ recv(sk-B, MSG_PEEK)<br />
¡¡invalidar!! -&gt; contador de referencias de archivo de sk-A : 1 -&gt; 2<br />
<br />
close(sk-B)<br />
-&gt; contador de referencias de archivo de sk-B : 2 -&gt; 1<br />
unix_vertex_dead(sk-B)<br />
-&gt; true<br />
<br />
Inicialmente, el contador de referencias de archivo de sk-A es 1 por el descriptor de archivo en tránsito en la cola de recepción de sk-B. La recolección de basura (GC) piensa que sk-A está muerto porque el contador de referencias de archivo es el mismo que el número de sus descriptores de archivo en tránsito.<br />
<br />
Sin embargo, el contador de referencias de archivo de sk-A es incrementado silenciosamente por MSG_PEEK, lo que invalida la evaluación anterior.<br />
<br />
En este momento, el contador de referencias de archivo de sk-B es 2; uno por el descriptor de archivo abierto, y uno por el descriptor de archivo en tránsito en sk-A. El close() (cierre) subsiguiente libera un contador de referencias por el primero.<br />
<br />
Finalmente, la recolección de basura (GC) concluye incorrectamente que tanto sk-A como sk-B están muertos.<br />
<br />
Una opción es restaurar la &#39;danza de bloqueo&#39; en unix_peek_fds(), pero podemos resolver esto de manera más elegante gracias al nuevo algoritmo.<br />
<br />
El punto es que el problema no ocurre sin el close() (cierre) subsiguiente y en realidad no necesitamos sincronizar MSG_PEEK con la detección de SCC muertos.<br />
<br />
Cuando ocurre el problema, close() (el cierre) y la recolección de basura (GC) tocan el mismo contador de referencias de archivo. Si la recolección de basura (GC) ve que el contador de referencias es decrementado por close() (el cierre), puede simplemente abandonar la recolección de basura del SCC.<br />
<br />
Por lo tanto, solo necesitamos señalar la condición de carrera durante MSG_PEEK con una barrera de memoria adecuada para hacerla visible a la recolección de basura (GC).<br />
<br />
Usemos seqcount_t para notificar a la recolección de basura (GC) cuando ocurre MSG_PEEK y permitirle aplazar el SCC a la siguiente ejecución.<br />
<br />
De esta manera, no se necesita bloqueo en el lado de MSG_PEEK, y podemos evitar imponer una penalización a cada MSG_PEEK innecesariamente.<br />
<br />
Tenga en cuenta que podemos reintentar dentro de unix_scc_dead() si se detecta MSG_PEEK, pero no lo hacemos para evitar la &#39;salpicadura&#39; de tareas colgadas por llamadas abusivas a MSG_PEEK.



