Vulnerabilidad en kernel de Linux (CVE-2024-47741)
Gravedad CVSS v3.1:
ALTA
Tipo:
CWE-362
Ejecución concurrente utilizando recursos compartidos con una incorrecta sincronización (Condición de carrera)
Fecha de publicación:
21/10/2024
Última modificación:
23/10/2024
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: btrfs: arreglo de ejecución que establece el archivo privado en lseek concurrente usando el mismo fd Al realizar llamadas al sistema lseek(2) concurrentes contra el mismo descriptor de archivo, usando múltiples subprocesos que pertenecen al mismo proceso, tenemos una ventana de tiempo corta donde ocurre una ejecución y puede resultar en una pérdida de memoria. La ejecución ocurre así: 1) Un programa abre un descriptor de archivo para un archivo y luego genera dos subprocesos (con la librería pthreads por ejemplo), llamémoslos tarea A y tarea B; 2) La tarea A llama a lseek con SEEK_DATA o SEEK_HOLE y termina en file.c:find_desired_extent() mientras mantiene un bloqueo de lectura en el inodo; 3) Al comienzo de find_desired_extent(), extrae el puntero private_data del archivo en una variable local llamada 'private', que tiene un valor de NULL; 4) La tarea B también llama a lseek con SEEK_DATA o SEEK_HOLE, bloquea el inodo en modo compartido e ingresa a file.c:find_desired_extent(), donde también extrae file->private_data en su variable local 'private', que tiene un valor NULL; 5) Debido a que vio un archivo privado NULL, la tarea A asigna una estructura privada y la asigna a la estructura de archivo; 6) La tarea B también vio un archivo privado NULL, por lo que también asigna su propio archivo privado y luego lo asigna a la misma estructura de archivo, ya que ambas tareas están usando el mismo descriptor de archivo. En este punto filtramos la estructura privada asignada por la tarea A. Además de la fuga de memoria, también está el detalle de que ambas tareas terminan usando el mismo registro de estado en caché en la estructura privada (struct btrfs_file_private::llseek_cached_state), lo que puede resultar en un problema de use after free, ya que una tarea puede liberarlo mientras la otra todavía lo está usando (solo una tarea tomó un recuento de referencia en él). Además, compartir el estado en caché no es una buena idea, ya que podría resultar en resultados incorrectos en el futuro; en este momento no debería ser un problema porque termina siendo utilizado solo en extended-io-tree.c:count_range_bits() donde realizamos la validación de rango antes de usar el estado en caché. Solucione esto protegiendo la asignación privada y la verificación de un archivo mientras mantiene el spinlock del inodo y realice un seguimiento de la tarea que asignó el privado, de modo que solo lo use esa tarea para evitar problemas de use after free con el registro de estado en caché, así como potencialmente usarlo incorrectamente en el futuro.
Impacto
Puntuación base 3.x
7.00
Gravedad 3.x
ALTA
Productos y versiones vulnerables
CPE | Desde | Hasta |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.2 (incluyendo) | 6.6.54 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.7 (incluyendo) | 6.10.13 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.11 (incluyendo) | 6.11.2 (excluyendo) |
Para consultar la lista completa de nombres de CPE con productos y versiones, ver esta página