Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

Vulnerabilidad en kernel de Linux (CVE-2024-50106)

Gravedad CVSS v3.1:
ALTA
Tipo:
CWE-416 Utilización después de liberación
Fecha de publicación:
05/11/2024
Última modificación:
11/12/2024

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: nfsd: arregla la ejecución entre laundromat y free_stateid. Hay una ejecución entre el manejo de laundromat de delegaciones revocadas y un cliente que envía la operación free_stateid. El hilo de laundromat encuentra que la delegación ha expirado y necesita ser revocada, por lo que marca el stid de delegación revocado y lo pone en una lista de reaper, pero luego desbloquea el bloqueo de estado y la revocación de delegación real ocurre sin el bloqueo. Una vez que el stid está marcado como revocado, un hilo de procesamiento de free_stateid en ejecución hace lo siguiente: (1) llama a list_del_init() que lo elimina de la lista de reaper y (2) libera la estructura del stid de delegación. El hilo de laundromat termina sin llamar a la función revoke_delegation() para esta delegación en particular, pero eso significa que no liberará la concesión de bloqueo que existe en el archivo. Ahora, una nueva apertura para este archivo llega y termina encontrando que la lista de arrendamientos no está vacía y llama a nfsd_breaker_owns_lease() que termina intentando desreferenciar un stateid de delegación liberado. Lo que genera la siguiente advertencia de KASAN de use-after-free: kernel: == ... 2069.0.0.0.0 08/03/2024 núcleo: Seguimiento de llamadas: núcleo: dump_backtrace+0x98/0x120 núcleo: show_stack+0x1c/0x30 núcleo: dump_stack_lvl+0x80/0xe8 núcleo: print_address_description.constprop.0+0x84/0x390 núcleo: print_report+0xa4/0x268 núcleo: kasan_report+0xb4/0xf8 núcleo: __asan_report_load8_noabort+0x1c/0x28 núcleo: nfsd_breaker_owns_lease+0x140/0x160 [nfsd] núcleo: nfsd_file_do_acquire+0xb3c/0x11d0 [nfsd] núcleo: nfsd_file_acquire_opened+0x84/0x110 [nfsd] núcleo: nfs4_get_vfs_file+0x634/0x958 [nfsd] núcleo: nfsd4_process_open2+0xa40/0x1a40 [nfsd] núcleo: nfsd4_open+0xa08/0xe80 [nfsd] núcleo: nfsd4_proc_compound+0xb8c/0x2130 [nfsd] núcleo: nfsd_dispatch+0x22c/0x718 [nfsd] núcleo: svc_process_common+0x8e8/0x1960 [sunrpc] núcleo: svc_process+0x3d4/0x7e0 [sunrpc] núcleo: svc_handle_xprt+0x828/0xe10 [sunrpc] kernel: svc_recv+0x2cc/0x6a8 [sunrpc] kernel: nfsd+0x270/0x400 [nfsd] kernel: kthread+0x288/0x310 kernel: ret_from_fork+0x10/0x20 Este parche propone una solución basada en agregar 2 nuevos valores de stid adicionales sc_status que ayudan a coordinar entre la lavandería y otras operaciones (nfsd4_free_stateid() y nfsd4_delegreturn()). Primero, para asegurarse de que una vez que el stid esté marcado como revocado, no sea eliminado por nfsd4_free_stateid(), la lavandería tome una referencia en el stateid. Luego, al coordinar si el stid se ha colocado en la lista cl_revoked o si estamos procesando FREE_STATEID y debemos asegurarnos de eliminarlo de la lista, cada uno verifica ese estado y actúa en consecuencia. Si laundromat ha agregado a la lista cl_revoke antes de la llegada de FREE_STATEID, entonces nfsd4_free_stateid() sabe eliminarlo de la lista. Si nfsd4_free_stateid() encuentra que las operaciones llegaron antes de que laundromat lo haya colocado en la lista cl_revoke, marca el estado como liberado y luego laundromat ya no lo agregará a la lista. Además, para nfsd4_delegreturn() cuando buscamos el stid especificado, necesitamos acceder a los stid que están marcados como eliminados o liberables, significa que laundromat ha comenzado a procesarlo pero no ha terminado y este delegreturn debe devolver nfserr_deleg_revoked y no nfserr_bad_stateid. Este último no activará un FREE_STATEID y la falta del mismo dejará este stid en la lista cl_revoked indefinidamente.

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.17 (incluyendo) 6.11.6 (excluyendo)
cpe:2.3:o:linux:linux_kernel:6.12:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.12:rc4:*:*:*:*:*:*