Vulnerabilidad en kernel de Linux (CVE-2024-26960)
Gravedad CVSS v3.1:
MEDIA
Tipo:
CWE-362
Ejecución concurrente utilizando recursos compartidos con una incorrecta sincronización (Condición de carrera)
Fecha de publicación:
01/05/2024
Última modificación:
20/03/2025
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: mm: swap: corrige la ejecución entre free_swap_and_cache() y swapoff() Anteriormente existía una ventana teórica donde swapoff() podía ejecutar y desmantelar un swap_info_struct mientras se realizaba una llamada a free_swap_and_cache(). corriendo en otro hilo. Esto podría causar, entre otras malas posibilidades, que swap_page_trans_huge_swapped() (llamado por free_swap_and_cache()) acceda a la memoria liberada para swap_map. Este es un problema teórico y no he podido provocarlo a partir de un caso de prueba. Pero ha habido un acuerdo basado en la revisión del código de que esto es posible (ver enlace a continuación). Solucionarlo usando get_swap_device()/put_swap_device(), lo que detendrá swapoff(). Hubo una verificación adicional en _swap_info_get() para confirmar que la entrada de intercambio no era gratuita. Esto no está presente en get_swap_device() porque en general no tiene sentido debido a la ejecución entre obtener la referencia y el intercambio. Así que agregué una verificación equivalente directamente en free_swap_and_cache(). Detalles de cómo provocar un posible problema (gracias a David Hildenbrand por derivar esto): --8<----- __swap_entry_free() podría ser el último usuario y dar como resultado "count == SWAP_HAS_CACHE". swapoff->try_to_unuse() se detendrá tan pronto como si->inuse_pages==0. Entonces la pregunta es: ¿alguien podría reclamar la publicación y activar si->inuse_pages==0, antes de que completemos swap_page_trans_huge_swapped()? Imagine lo siguiente: folio de 2 MiB en el swapcache. Sólo 2 subpáginas siguen siendo referencias mediante entradas de intercambio. El proceso 1 todavía hace referencia a la subpágina 0 mediante la entrada de intercambio. El proceso 2 todavía hace referencia a la subpágina 1 mediante la entrada de intercambio. El proceso 1 se cierra. Llama a free_swap_and_cache(). -> count == SWAP_HAS_CACHE [luego, adelantado en el hipervisor, etc.] El proceso 2 se cierra. Llama a free_swap_and_cache(). -> count == SWAP_HAS_CACHE El proceso 2 continúa, pasa swap_page_trans_huge_swapped() y llama a __try_to_reclaim_swap(). __try_to_reclaim_swap()->folio_free_swap()->delete_from_swap_cache()-> put_swap_folio()->free_swap_slot()->swapcache_free_entries()-> swap_entry_free()->swap_range_free()-> ... WRITE_ONCE(si->inuse_pages, si->inuse_pages - nr_entries); ¿Qué impide que el intercambio tenga éxito después de que el proceso 2 recuperó el caché de intercambio pero antes de que el proceso 1 terminara su llamada a swap_page_trans_huge_swapped()? --8<-----
Impacto
Puntuación base 3.x
5.50
Gravedad 3.x
MEDIA
Productos y versiones vulnerables
CPE | Desde | Hasta |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 4.11 (incluyendo) | 5.10.215 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (incluyendo) | 5.15.154 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.16 (incluyendo) | 6.1.84 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.2 (incluyendo) | 6.6.24 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.7 (incluyendo) | 6.7.12 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.8 (incluyendo) | 6.8.3 (excluyendo) |
cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:* |
Para consultar la lista completa de nombres de CPE con productos y versiones, ver esta página
Referencias a soluciones, herramientas e información
- https://git.kernel.org/stable/c/0f98f6d2fb5fad00f8299b84b85b6bc1b6d7d19a
- https://git.kernel.org/stable/c/1ede7f1d7eed1738d1b9333fd1e152ccb450b86a
- https://git.kernel.org/stable/c/2da5568ee222ce0541bfe446a07998f92ed1643e
- https://git.kernel.org/stable/c/363d17e7f7907c8e27a9e86968af0eaa2301787b
- https://git.kernel.org/stable/c/3ce4c4c653e4e478ecb15d3c88e690f12cbf6b39
- https://git.kernel.org/stable/c/82b1c07a0af603e3c47b906c8e991dc96f01688e
- https://git.kernel.org/stable/c/d85c11c97ecf92d47a4b29e3faca714dc1f18d0d
- https://git.kernel.org/stable/c/0f98f6d2fb5fad00f8299b84b85b6bc1b6d7d19a
- https://git.kernel.org/stable/c/1ede7f1d7eed1738d1b9333fd1e152ccb450b86a
- https://git.kernel.org/stable/c/2da5568ee222ce0541bfe446a07998f92ed1643e
- https://git.kernel.org/stable/c/363d17e7f7907c8e27a9e86968af0eaa2301787b
- https://git.kernel.org/stable/c/3ce4c4c653e4e478ecb15d3c88e690f12cbf6b39
- https://git.kernel.org/stable/c/82b1c07a0af603e3c47b906c8e991dc96f01688e
- https://git.kernel.org/stable/c/d85c11c97ecf92d47a4b29e3faca714dc1f18d0d
- https://lists.debian.org/debian-lts-announce/2024/06/msg00017.html