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

Vulnerabilidad en kernel de Linux (CVE-2025-22077)

Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
16/04/2025
Última modificación:
25/04/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: smb: cliente: Corregir el desequilibrio en el recuento de referencias de netns que causa fugas y use-after-free. el commit ef7134c7fc48 ("smb: cliente: Corregir el use-after-free del espacio de nombres de red") intentó corregir un problema de use-after-free de netns ajustando manualmente los recuentos de referencias mediante sk->sk_net_refcnt y sock_inuse_add(). Sin embargo, una confirmación posterior e9f2517a3e18 ("smb: cliente: Corregir el bloqueo de los temporizadores TCP después de rmmod") indicó que la configuración manual de sk->sk_net_refcnt en la primera confirmación era técnicamente incorrecta, ya que sk->sk_net_refcnt solo debe configurarse para sockets de usuario. Esto provocó problemas como que los temporizadores TCP no se borraran correctamente al cerrar. La segunda confirmación se adaptó a un modelo que simplemente almacena una referencia netns adicional para server->ssocket mediante get_net() y la elimina al desmantelar el servidor. Sin embargo, persisten algunas deficiencias en el equilibrio entre get_net() y put_net(), añadidas por estas confirmaciones. El manejo incompleto de las referencias en estas correcciones genera dos problemas: 1. Fugas de recuento de referencias de netns[1]. El proceso del problema es el siguiente: ``` mount.cifs cifsd cifs_do_mount cifs_mount cifs_mount_get_session cifs_get_tcp_session get_net() /* Primero, obtener net. */ ip_connect generic_ip_connect /* Intentar el puerto 445 */ get_net() ->connect() /* Error */ put_net() generic_ip_connect /* Intentar el puerto 139 */ get_net() /* Falta put_net() coincidente para este get_net().*/ cifs_get_smb_ses cifs_negotiate_protocol smb2_negotiate SMB2_negotiate cifs_send_recv wait_for_response cifs_demultiplex_thread cifs_read_from_socket cifs_readv_from_socket cifs_reconnect cifs_abort_connection sock_release(); server->ssocket = NULL; /* Falta put_net() aquí. */ generic_ip_connect get_net() ->connect() /* Error */ put_net() sock_release(); server->ssocket = NULL; free_rsp_buf ... clean_demultiplex_info /* Solo se llama una vez aquí. */ put_net() ``` Cuando se activa cifs_reconnect(), el servidor->ssocket se libera sin un put_net() correspondiente para la referencia obtenida previamente en generic_ip_connect(). Termina llamando a generic_ip_connect() de nuevo para reintentar get_net(). Después, el servidor->ssocket se establece en NULL en la ruta de error de generic_ip_connect(), y el recuento neto no se puede liberar en la función clean_demultiplex_info() final. 2. Posible use-after-free. El esquema actual de recuento de referencias puede generar un posible problema de use-after-free en el siguiente escenario: ``` cifs_do_mount cifs_mount cifs_mount_get_session cifs_get_tcp_session get_net() /* First get net */ ip_connect generic_ip_connect get_net() bind_socket kernel_bind /* failed */ put_net() /* after out_err_crypto_release label */ put_net() /* after out_err label */ put_net() ``` En el proceso de gestión de excepciones donde falla la vinculación del socket, las llamadas get_net() y put_net() están desequilibradas, lo que puede provocar que el recuento de referencias server->net baje a cero y se libere prematuramente. Para solucionar ambos problemas, este parche vincula el recuento de referencias netns ---truncated---

Impacto