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

Vulnerabilidad en kernel de Linux (CVE-2025-37931)

Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
20/05/2025
Última modificación:
19/12/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: btrfs: ajustar el inicio del bit de la subpágina en función del tamaño del sector Al ejecutar máquinas con un tamaño de página de 64k y un tamaño de nodo de 16k, comenzamos a ver corrupción en el registro del árbol en producción. Esto resultó ser porque a veces no escribíamos bloques sucios, por lo que, de hecho, afecta a todas las escrituras de metadatos. Al escribir un EB de subpágina, escaneamos el mapa de bits de la subpágina en busca de un rango sucio. Si el rango no está sucio, hacemos bit_start++; para pasar al siguiente bit. El problema es que el mapa de bits se basa en la cantidad de sectores que tiene un EB. Entonces, en este caso, tenemos un tamaño de página de 64k, un tamaño de nodo de 16k, pero un tamaño de sector de 4k. Esto significa que nuestro mapa de bits es de 4 bits para cada nodo. Con un tamaño de página de 64k, terminamos con 4 nodos por página. Para hacer esto más fácil así es como se ve todo [0 16k 32k 48k ] dirección lógica [0 4 8 12 ] desplazamiento del árbol de radix [ página 64k ] folio [ 16k eb ][ 16k eb ][ 16k eb ][ 16k eb ] búferes de extensión [ | | | | | | | | | | | | | | | | ] mapa de bits Ahora usamos todo nuestro direccionamiento basado en fs_info->sectorsize_bits, así que como puedes ver arriba nuestro eb->start de 16k se convierte en la entrada de radix 4. Cuando encontramos un rango sucio para nuestro eb, hacemos correctamente bit_start += sectores_per_node, porque si empezamos en el bit 0, el siguiente bit para el siguiente eb es 4, para corresponder a eb->start 16k. Sin embargo, si nuestro rango está limpio, haremos bit_start++, que ahora nos pondrá en un desplazamiento desde nuestras entradas del árbol de radix. En nuestro caso, supongamos que la primera vez que comprobamos el mapa de bits, el bloque no está sucio, incrementamos bit_start para que ahora sea == 1, y luego hacemos un bucle y comprobamos de nuevo. Esta vez está sucio, y vamos a encontrar ese inicio usando la siguiente ecuación start = folio_start + bit_start * fs_info->sectorsize; así que en el caso anterior, eb->start 0 ahora está sucio, y calculamos start como 0 + 1 * fs_info->sectorsize = 4096 4096 >> 12 = 1 Ahora estamos buscando el árbol de bases para 1, y no encontraremos un eb. Lo que es peor es que ahora estamos usando bit_start == 1, así que hacemos bit_start += sectores_por_nodo, que ahora es 5. Si ese eb está sucio, nos encontraremos con lo mismo, veremos un desplazamiento que no está rellenado en el árbol de bases, y ahora estamos omitiendo la escritura de los búferes de extensión sucios. La mejor solución es no usar sectorsize_bits para direccionar nodos, pero ese es un cambio mayor. Dado que se trata de un problema de corrupción del sistema de archivos, corríjalo simplemente usando siempre sectores_por_nodo para incrementar el bit de inicio.

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.13 (incluyendo) 6.1.151 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (incluyendo) 6.6.105 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (incluyendo) 6.12.28 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.13 (incluyendo) 6.14.6 (excluyendo)
cpe:2.3:o:linux:linux_kernel:6.15:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.15:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.15:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.15:rc4:*:*:*:*:*:*
cpe:2.3:o:debian:debian_linux:11.0:*:*:*:*:*:*:*