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

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

Gravedad CVSS v3.1:
MEDIA
Tipo:
CWE-125 Lectura fuera de límites
Fecha de publicación:
01/05/2024
Última modificación:
08/04/2025

Descripción

En el kernel de Linux, se resolvió la siguiente vulnerabilidad: KVM: x86/mmu: x86: no desborde lpage_info al verificar los atributos. Corrija KVM_SET_MEMORY_ATTRIBUTES para no desbordar la matriz lpage_info y activar KASAN splat, como se ve en la autoprueba private_mem_conversions_test. Cuando los atributos de memoria se configuran en un rango GFN, ese rango tendrá propiedades específicas aplicadas al TDP. No se puede utilizar una página enorme cuando los atributos son inconsistentes, por lo que están deshabilitados para aquellas páginas enormes específicas. Por razones internas de KVM, tampoco se permite que páginas grandes abarquen ranuras de memoria adyacentes, independientemente de si la memoria de respaldo podría asignarse como enorme. Qué GFN admite qué tamaños de página enormes se rastrea mediante una serie de matrices 'lpage_info' en el memslot, de estructuras 'kvm_lpage_info'. Cada índice de lpage_info contiene una matriz asignada por vmalloc para un tamaño de página compatible específico. kvm_lpage_info indica si se admite una página enorme específica (GFN y tamaño de página) en la ranura de memoria. Estas matrices incluyen índices para páginas grandes de cabecera y cola no alineadas. Para evitar que páginas grandes abarquen ranuras de memoria adyacentes, se incrementa el recuento en head y tail kvm_lpage_info cuando se asigna la ranura de memoria, pero no permitir páginas grandes para memoria que tenga atributos mixtos debe hacerse de una manera más complicada. Durante KVM_SET_MEMORY_ATTRIBUTES ioctl, KVM actualiza lpage_info para cada ranura de memoria en el rango que tiene atributos que no coinciden. KVM hace esto una ranura de memoria a la vez y marca un bit especial, KVM_LPAGE_MIXED_FLAG, en kvm_lpage_info para cualquier página grande. Este bit es esencialmente un recuento elevado permanentemente. Por lo tanto, las páginas grandes no se asignarán para GFN en ese tamaño de página si el recuento es elevado en cualquier caso: una página principal o final enorme no alineada con la ranura de memoria o si KVM_LPAGE_MIXED_FLAG está configurado porque tiene atributos mixtos. Para determinar si una página enorme tiene atributos consistentes, la operación KVM_SET_MEMORY_ATTRIBUTES verifica una matriz x para asegurarse de que tenga consistentemente el atributo entrante. Dado que las páginas grandes de nivel 1 están alineadas con las páginas grandes de nivel, se emplea una optimización. Siempre que se verifiquen primero las páginas grandes de nivel - 1, puede simplemente verificarlas y asumir que si cada página enorme de nivel - 1 contenida dentro de la página enorme de tamaño de nivel no está mezclada, entonces la página enorme de tamaño de nivel no está mezclada. Esta optimización ocurre en el ayudante Hugepage_has_attrs(). Desafortunadamente, aunque la matriz kvm_lpage_info que representa el tamaño de página 'nivel' contendrá una entrada para una página final no alineada de nivel de tamaño, la matriz para el nivel - 1 no contendrá una entrada para cada GFN en el nivel de tamaño de página. La matriz de nivel 1 solo contendrá un índice para cualquier región no alineada cubierta por el tamaño de página enorme de nivel 1, que puede ser una región más pequeña. Entonces, esto hace que la optimización desborde el nivel - 1 kvm_lpage_info y realice una lectura vmalloc fuera de los límites. En algunos casos de páginas principales y finales donde podría ocurrir un desbordamiento, las personas que llaman omiten la operación por completo ya que KVM_LPAGE_MIXED_FLAG no es necesario para evitar páginas grandes como se analizó anteriormente. Pero para las ranuras de memoria que son más pequeñas que el tamaño de página de 1 GB, llama a hugepage_has_attrs(). En este caso, la página enorme es tanto la página principal como la final. --truncado---

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.8 (incluyendo) 6.8.8 (excluyendo)
cpe:2.3:o:linux:linux_kernel:6.9:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.9:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.9:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.9:rc4:*:*:*:*:*:*