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

Vulnerabilidad en kernel de Linux (CVE-2024-50200)

Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
08/11/2024
Última modificación:
03/11/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: maple_tree: corregir la corrupción del árbol en el almacén de expansión Serie de parches "maple_tree: corregir la corrupción del árbol en el almacén de expansión", v3. Ha habido un error de corrupción del árbol de maple desagradable pero sutil que parece haber existido desde el inicio del algoritmo. Este error parece mucho más probable que ocurra desde el commit f8d112a4e657 ("mm/mmap: evitar poner a cero el árbol vma en mmap_region()"), que es el punto en el que comenzaron a enviarse informes sobre este error. Nos enteramos definitivamente del error gracias a los amables esfuerzos de Bert Karwatzki, quien me ayudó enormemente a poder rastrearlo e identificar la causa. El error surge cuando se intenta realizar un almacenamiento de expansión en dos nodos de hoja, donde el nodo de hoja derecho es el hijo más a la derecha del padre compartido, y el almacenamiento consume por completo el nodo de modo derecho. Esto da como resultado que mas_wr_spanning_store() duplique por error las entradas nuevas y existentes en el pivote máximo dentro del rango, y por lo tanto la corrupción del árbol de maple. El parche de corrección corrige esto detectando este escenario y no permitiendo la copia duplicada errónea. El mensaje de confirmación del parche de corrección detalla en gran medida cómo ocurre esto. Esta serie también incluye una prueba que reproduce el problema de manera confiable y afirma que la corrección funciona correctamente. Bert ha probado amablemente la corrección y confirmó que resolvió sus problemas. Además, Mikhail Gavrilov informó amablemente lo que parece ser exactamente el mismo error, que esta corrección también debería resolver. Este parche (de 2): Ha habido un error sutil presente en la implementación del árbol de maple desde su inicio. Esto surge de cómo se realizan los almacenamientos: cuando se produce un almacenamiento, sobrescribirá los rangos superpuestos y ajustará el árbol según sea necesario para adaptarse a esto. Un rango siempre puede abarcar en última instancia dos nodos de hoja. En este caso, recorremos los dos nodos de hoja, determinamos qué elementos no se sobrescriben a la izquierda y a la derecha del inicio y el final de los rangos respectivamente y luego reequilibramos el árbol para que contenga estas entradas y la recién insertada. Este tipo de almacenamiento se denomina "almacén de expansión" y se implementa mediante mas_wr_spanning_store(). Para llegar a esta etapa, mas_store_gfp() invoca a mas_wr_preallocate(), mas_wr_store_type() y mas_wr_walk() a su vez para recorrer el árbol y actualizar el objeto (mas) para atravesar la ubicación donde se debe realizar la escritura, determinando su tipo de almacenamiento. Cuando se requiere un almacenamiento de expansión, esta función devuelve falso y se detiene en el nodo principal que contiene el rango de destino, y mas_wr_store_type() marca mas->store_type como wr_spanning_store para denotar este hecho. Cuando vamos a realizar el almacenamiento en mas_wr_spanning_store(), primero determinamos los elementos DESPUÉS del FINAL del rango que deseamos almacenar (es decir, a la derecha de la entrada que se insertará); lo hacemos caminando hasta el SIGUIENTE pivote en el árbol (es decir, r_mas.last + 1), comenzando en el nodo que acabamos de determinar que contiene el rango sobre el que pretendemos escribir. Luego dirigimos nuestra atención a las entradas a la izquierda de la entrada que estamos insertando, cuyo estado está representado por l_mas, y las copiamos en un "nodo grande", que es un nodo especial que contiene suficientes ranuras para contener los datos de dos nodos hoja. Luego copiamos la entrada que deseamos almacenar inmediatamente después de esto; la copia y la inserción de la nueva entrada se realiza mediante mas_store_b_node(). Después de esto, copiamos los elementos a la derecha del final del rango que estamos insertando, si no hemos excedido la longitud del nodo (es decir, r_mas.offset <= r_mas.end). ---truncado---

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.1 (incluyendo) 6.1.114 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (incluyendo) 6.6.58 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (incluyendo) 6.11.5 (excluyendo)
cpe:2.3:o:linux:linux_kernel:6.12:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc3:*:*:*:*:*:*