Vulnerabilidad en kernel de Linux (CVE-2024-40918)
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
12/07/2024
Última modificación:
12/07/2024
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: parisc: intenta corregir fallas de segmentación aleatoria en compilaciones de paquetes. Los sistemas PA-RISC con procesadores PA8800 y PA8900 han tenido problemas con fallas de segmentación aleatoria durante muchos años. Los sistemas con procesadores anteriores son mucho más estables. Los sistemas con procesadores PA8800 y PA8900 tienen una gran caché L2 que necesita un vaciado por página para un rendimiento decente cuando se vacía un rango grande. La caché combinada en estos sistemas también es más sensible a alias no equivalentes que las cachés de sistemas anteriores. La mayoría de los fallos de segmentación aleatoria que he observado parecen ser daños en la memoria asignada mediante mmap y malloc. Mi primer intento de solucionar los fallos aleatorios no funcionó. Al revisar el código de caché, me di cuenta de que había dos problemas que el código existente no manejaba correctamente. Ambos se relacionan con la entrada de caché. Otro problema es que la actualidad en las PTE es picante. 1) Los cachés PA-RISC tienen mente propia y pueden cargar especulativamente datos e instrucciones para una página siempre que haya una entrada en el TLB para la página que permita la entrada. Los TLB son locales para cada CPU. Por lo tanto, la entrada TLB de una página debe eliminarse antes de eliminarla. Esto es particularmente importante en los sistemas SMP. En algunas de las rutinas de vaciado, se llamaría a la rutina de vaciado y luego se purgaría la entrada TLB. Esto se debía a que la rutina de lavado necesitaba la entrada TLB para realizar el lavado. 2) Mi enfoque inicial para intentar solucionar las fallas aleatorias fue intentar usar Flush_cache_page_if_present para todas las operaciones de descarga. En realidad, esto empeoró las cosas y provocó un par de bloqueos de hardware. Finalmente me di cuenta de que algunas líneas no se estaban borrando porque el código de verificación del pte era picante. Esto resultó en asignaciones aleatorias no equivalentes a páginas físicas. La descarga tmpalias __flush_cache_page configura su propia entrada TLB y no necesita la entrada TLB existente. Siempre que podamos encontrar el puntero pte de la página vm, podemos obtener el pfn y la dirección física de la página. También podemos purgar la entrada TLB de la página antes de realizar el vaciado. Además, __flush_cache_page utiliza una entrada TLB especial que inhibe la entrada de caché. Al cambiar las asignaciones de páginas, debemos asegurarnos de que las líneas se eliminen del caché. No es suficiente simplemente borrar las líneas de la memoria, ya que pueden volver. Esto dejó en claro que necesitábamos implementar todas las operaciones de vaciado necesarias utilizando rutinas tmpalias. Esto incluye vaciados para páginas de usuario y de kernel. Después de modificar el código para usar tmpalias vaciados, quedó claro que los errores de segmentación aleatoria no se resolvieron por completo. La frecuencia de fallas fue peor en sistemas con 64 MB L2 (PA8900) y sistemas con más CPU (rp4440). La advertencia que agregué a Flush_cache_page_if_present para detectar páginas que no se podían vaciar se activaba con frecuencia en algunos sistemas. Helge y yo miramos las páginas que no se podían vaciar y descubrimos que la PTE estaba vacía o era una página de intercambio. Ignorar las páginas que se intercambiaron parecía estar bien, pero las páginas con PTE borradas parecían problemáticas. Miré rutinas relacionadas con pte_clear y noté ptep_clear_flush. La implementación predeterminada simplemente vacía la entrada TLB. Sin embargo, era obvio que en París también necesitamos vaciar la página de caché. Si no limpiamos la página de caché, quedarán líneas obsoletas en la caché y provocarán daños aleatorios. Una vez que se borra una PTE, no hay forma de encontrar la dirección física asociada con la PTE y borrar la página asociada más adelante. ---truncado---