Vulnerabilidad en kernel de Linux (CVE-2024-45003)
Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
04/09/2024
Última modificación:
05/11/2024
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: vfs: No desalojar inodo bajo el contexto de recorrido lru de inodo El proceso de recuperación de inodo (ver función prune_icache_sb) recopila todos los inodos recuperables y los marca con el indicador I_FREEING al principio, en ese momento, otros procesos se atascarán si intentan obtener estos inodos (ver función find_inode_fast), luego el proceso de recuperación destruye los inodos mediante la función dispose_list(). Algunos sistemas de archivos (por ejemplo, ext4 con la función ea_inode, ubifs con xattr) pueden realizar una búsqueda de inodo en la función de devolución de llamada de expulsión de inodo, si la búsqueda de inodo se opera bajo el contexto de recorrido lru de inodo, pueden ocurrir problemas de interbloqueo. Caso 1: En la función ext4_evict_inode(), la búsqueda de inodo ea podría ocurrir si la característica ea_inode está habilitada, el proceso de búsqueda se quedará atascado bajo el contexto de desalojo de esta manera: 1. El archivo A tiene un inodo i_reg y un inodo ea i_ea 2. getfattr(A, xattr_buf) // i_ea se agrega a lru // lru->i_ea 3. Luego, los siguientes tres procesos se ejecutan de esta manera: PA PB echo 2 > /proc/sys/vm/drop_caches shrink_slab prune_dcache_sb // i_reg se agrega a lru, lru->i_ea->i_reg prune_icache_sb list_lru_walk_one inode_lru_isolate i_ea->i_state |= I_FREEING // establece el estado del inodo inode_lru_isolate __iget(i_reg) spin_unlock(&i_reg->i_lock) spin_unlock(lru_lock) rm archivo A i_reg->nlink = 0 iput(i_reg) // i_reg->nlink es 0, desalojar ext4_evict_inode ext4_xattr_delete_inode ext4_xattr_inode_dec_ref_all ext4_xattr_inode_iget ext4_iget(i_ea->i_ino) iget_locked find_inode_fast __wait_on_freeing_inode(i_ea) ----? Bloqueo AA dispose_list // no puede ser ejecutado por prune_icache_sb wake_up_bit(&i_ea->i_state) Caso 2: En la función de escritura de inodo eliminado ubifs_jnl_write_inode(), el proceso de eliminación de archivo retiene BASEHD wbuf->io_mutex mientras obtiene el inodo xattr, que podría competir con el proceso de recuperación de inodo (el proceso de recuperación podría intentar bloquear wbuf->io_mutex de BASEHD en la función de desalojo de inodo), entonces ocurriría un problema de bloqueo ABBA de la siguiente manera: 1. El archivo A tiene un inodo ia y un xattr (con un inodo ixa), el archivo B normal tiene un inodo ib y un xattr. 2. getfattr(A, xattr_buf) // ixa se agrega a lru // lru->ixa 3. Luego, los siguientes tres procesos se ejecutan de esta manera: PA PB PC echo 2 > /proc/sys/vm/drop_caches shrink_slab prune_dcache_sb // ib e ia se agregan a lru, lru->ixa->ib->ia prune_icache_sb list_lru_walk_one inode_lru_isolate ixa->i_state |= I_FREEING // establece el estado del inodo inode_lru_isolate __iget(ib) spin_unlock(&ib->i_lock) spin_unlock(lru_lock) rm archivo B ib->nlink = 0 rm archivo A iput(ia) ubifs_evict_inode(ia) ubifs_jnl_delete_inode(ia) ubifs_jnl_write_inode(ia) make_reservation(BASEHD) // Bloquear wbuf->io_mutex ubifs_iget(ixa->i_ino) iget_locked find_inode_fast __wait_on_freeing_inode(ixa) | iput(ib) // ib->nlink es 0, desalojar | ubifs_evict_inode | ubifs_jnl_delete_inode(ib) ? ubifs_jnl_write_inode Bloqueo ABBA ?-----make_reservation(BASEHD) dispose_list // no puede ser ejecutado por prune_icache_sb wake_up_bit(&ixa->i_state) Corrija el posible bloqueo utilizando el nuevo indicador de estado de inodo I_LRU_ISOLATING para fijar el inodo en la memoria mientras inode_lru_isolate( ---truncado---
Impacto
Puntuación base 3.x
4.70
Gravedad 3.x
MEDIA
Productos y versiones vulnerables
CPE | Desde | Hasta |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 4.13 (incluyendo) | 5.4.283 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.5 (incluyendo) | 5.10.225 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (incluyendo) | 5.15.166 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.16 (incluyendo) | 6.1.107 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.2 (incluyendo) | 6.6.48 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.7 (incluyendo) | 6.10.7 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:6.11:rc1:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.11:rc2:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.11:rc3:*:*:*:*:*:* |
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/03880af02a78bc9a98b5a581f529cf709c88a9b8
- https://git.kernel.org/stable/c/2a0629834cd82f05d424bbc193374f9a43d1f87d
- https://git.kernel.org/stable/c/3525ad25240dfdd8c78f3470911ed10aa727aa72
- https://git.kernel.org/stable/c/437741eba63bf4e437e2beb5583f8633556a2b98
- https://git.kernel.org/stable/c/9063ab49c11e9518a3f2352434bb276cc8134c5f
- https://git.kernel.org/stable/c/b9bda5f6012dd00372f3a06a82ed8971a4c57c32
- https://git.kernel.org/stable/c/cda54ec82c0f9d05393242b20b13f69b083f7e88