Vulnerabilidad en kernel de Linux (CVE-2021-47303)
Gravedad CVSS v3.1:
ALTA
Tipo:
CWE-416
Utilización después de liberación
Fecha de publicación:
21/05/2024
Última modificación:
26/12/2024
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: bpf: realiza un seguimiento correcto de los descriptores de poke del subprog y corrige el use-after-free. Los subprogramas llaman a map_poke_track(), pero en el lanzamiento del programa no hay ningún enlace para llamar a map_poke_untrack(). Sin embargo, al lanzar el programa, la memoria auxiliar (y la tabla de descriptores de inserción) se liberan aunque todavía tengamos una referencia a ella en la lista de elementos de los datos auxiliares del mapa. Cuando ejecutamos map_poke_run(), terminamos accediendo a la memoria liberada, lo que activa KASAN en prog_array_map_poke_run(): [...] [402.824689] ERROR: KASAN: use-after-free en prog_array_map_poke_run+0xc2/0x34e [402.824698] Lectura del tamaño 4 en la dirección ffff8881905a7940 mediante la tarea hubble-fgs/4337 [402.824705] CPU: 1 PID: 4337 Comm: hubble-fgs Contaminado: GI 5.12.0+ #399 [402.824715] Seguimiento de llamadas: [402.824719] x93/ 0xc2 [402.824727] print_address_description.constprop.0+0x1a/0x140 [402.824736]? prog_array_map_poke_run+0xc2/0x34e [402.824740]? prog_array_map_poke_run+0xc2/0x34e [ 402.824744] kasan_report.cold+0x7c/0xd8 [ 402.824752] ? prog_array_map_poke_run+0xc2/0x34e [ 402.824757] prog_array_map_poke_run+0xc2/0x34e [ 402.824765] bpf_fd_array_map_update_elem+0x124/0x1a0 [...] Los elementos en cuestión se recorren de la siguiente manera: for (i = 0; i < elem-> aux->tamaño_poke_tab; i++) { empujar = &elem->aux->poke_tab[i]; [...] El acceso a size_poke_tab es una lectura de 4 bytes, verificada verificando las compensaciones en el volcado de KASAN: [402.825004] La dirección con errores pertenece al objeto en ffff8881905a7800 que pertenece al caché kmalloc-1k de tamaño 1024 [402.825008] La dirección con errores se encuentra a 320 bytes dentro de una región de 1024 bytes [ffff8881905a7800, ffff8881905a7c00) La salida de error de bpf_prog_aux: struct bpf_prog_aux { [...] /* --- límite de cacheline 5 (320 bytes) --- */ u32 tamaño_poke_tab; /* 320 4 */ [...] En general, los subprogramas no necesariamente gestionan sus propias estructuras de datos. Por ejemplo, BTF func_info y linfo son sólo punteros a la estructura principal del programa. Esto permite realizar un recuento de referencias y una sanitización de estos últimos, lo que simplifica un poco su gestión. La estructura aux->poke_tab, sin embargo, no siguió esta lógica. La solución inicial propuesta para este error de use-after-free incorporó aún más el seguimiento de datos de inserción en el subprograma con un recuento de referencias adecuado. Sin embargo, Daniel y Alexei se preguntaron por qué tratábamos a estos objetos de manera especial; Estoy de acuerdo, es innecesario. La solución aquí elimina la asignación de la tabla de poke por subprograma y el seguimiento del mapa y, en su lugar, simplemente apunta el puntero aux->poke_tab a la tabla de poke del programa principal. De esta manera, el seguimiento de mapas se simplifica al programa principal y no necesitamos gestionarlos por subprograma. Esto también significa que bpf_prog_free_deferred(), que desenrolla el recuento de referencias del programa y libera objetos, debe garantizar que no intentemos liberar dos veces el poke_tab al liberar las estructuras de subprog. Esto se resuelve fácilmente haciendo NULL en el puntero poke_tab. El segundo detalle es garantizar que la lógica JIT por subprograma solo realice correcciones en las entradas poke_tab[] que posee. Para hacer esto, agregamos un puntero en la estructura poke para señalar el valor del subprograma para que los JIT puedan verificar fácilmente mientras recorren la estructura poke_tab si la entrada actual pertenece al programa actual. El puntero auxiliar es estable y, por tanto, adecuado para dicha comparación. ---truncado---
Impacto
Puntuación base 3.x
7.80
Gravedad 3.x
ALTA
Productos y versiones vulnerables
CPE | Desde | Hasta |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.10 (incluyendo) | 5.10.53 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (incluyendo) | 5.13.5 (excluyendo) |
cpe:2.3:o:linux:linux_kernel:5.14:rc1:*:*:*:*:*:* |
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/599148d40366bd5d1d504a3a8fcd65e21107e500
- https://git.kernel.org/stable/c/a9f36bf3613c65cb587c70fac655c775d911409b
- https://git.kernel.org/stable/c/f263a81451c12da5a342d90572e317e611846f2c
- https://git.kernel.org/stable/c/599148d40366bd5d1d504a3a8fcd65e21107e500
- https://git.kernel.org/stable/c/a9f36bf3613c65cb587c70fac655c775d911409b
- https://git.kernel.org/stable/c/f263a81451c12da5a342d90572e317e611846f2c