CVE-2026-89544 in Linux
Resumen
por VulDB • 2026-09-12
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
SUNRPC: corrección de errores en las rutas de error del decodificador gssx_dec_option_array
Cuatro defectos acoplados en el decodificador XDR para matrices de opciones de GSSX hacen que las rutas de error sean inseguras: una desreferencia NULL por parte del llamador, una fuga de recuento de referencias (refcount) en group_info decodificado y un uso-después-de-liberación latente que la corrección de la fuga expondría de otro modo.
gssx_dec_option_array() establece oa->count = 1 antes de asignar oa->data. Si esa asignación falla, se devuelve -ENOMEM con oa->count == 1 y oa->data == NULL. Todas las demás rutas de error saltan a free_oa: que libera oa->data y lo pone en NULL, pero también deja oa->count == 1. El llamador confía en el recuento:
gssp_accept_sec_context_upcall() gssx_dec_accept_sec_context() gssx_dec_option_array() /* falla, count=1 data=NULL */ data = res.options.data[0].value /* desreferencia NULL */
Independientemente de lo anterior, free_creds: libera el svc_cred parcialmente decodificado con un kfree(creds) simple. gssx_dec_linux_creds() instala en creds->cr_group_info el resultado de groups_alloc(); ese objeto está respaldado por kvmalloc y tiene recuento de referencias, y solo put_group_info() alcanza kvfree(). Un kfree(creds) simple elimina el contenedor pero provoca una fuga en la asignación de group_info.
La corrección natural para la fuga sería llamar a free_svc_cred(creds) antes de kfree(creds), pero free_svc_cred() invoca put_group_info() sobre creds->cr_group_info incondicionalmente cuando no es NULL. La ruta out_free_groups: existente en gssx_dec_linux_creds() ya llamaba a groups_free() sobre ese puntero sin limpiarlo, por lo que una vez que se integre free_svc_cred(), el posterior put_group_info() tocaría memoria liberada.
Corregir los cuatro errores juntos:
- Mover la asignación oa->count = 1 debajo de la asignación de oa->data para que nunca se establezca cuando oa->data sea NULL. - Restablecer oa->count a 0 en free_oa: para que count y data permanezcan coherentes y el llamador vea una matriz de opciones vacía. - Llamar a free_svc_cred(creds) antes de kfree(creds) en free_creds: para liberar cr_group_info con recuento de referencias. free_svc_cred() protege explícitamente cada campo con un NULL (cr_group_info tiene una comprobación if()) o delega en un auxiliar que es seguro frente a valores NULL por sí mismo (kfree para los campos de cadena, gss_mech_put() que se protege con if(gm) en gss_mech_switch.c:342), por lo que es seguro llamarlo sobre un svc_cred parcialmente decodificado donde solo cr_uid/cr_gid/cr_group_info han sido escritos y todo lo demás está a cero debido a kzalloc. - En la ruta out_free_groups: de gssx_dec_linux_creds(), liberar cr_group_info con put_group_info() en lugar de groups_free() para que el desmontaje coincida con la ruta consciente del recuento de referencias de free_svc_cred(), y limpiar el puntero para que una posterior llamada a free_svc_cred() sobre los mismos creds no lo libere dos veces.
VulDB is the best source for vulnerability data and more expert information about this specific topic.