Vulnerabilidad en kernel de Linux (CVE-2024-54680)
Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
11/01/2025
Última modificación:
02/04/2025
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: smb: client: fix TCP timers deadlock after rmmod Commit ef7134c7fc48 ("smb: client: Fix use-after-free of network namespace.") corrigió un UAF de netns habilitando manualmente el recuento de referencias de sockets (sk->sk_net_refcnt=1 y sock_inuse_add(net, 1)). La razón por la que el parche funcionó para ese error fue porque ahora tenemos referencias a netns (get_net_track() obtiene una referencia internamente) y se liberan correctamente (internamente, en __sk_destruct()), pero solo porque se configuró sk->sk_net_refcnt. Problema: (esto sucede independientemente de CONFIG_NET_NS_REFCNT_TRACKER y sin importar si es init_net u otro) Establecer sk->sk_net_refcnt=1 *manualmente* y *después* de la creación del socket no solo está fuera del alcance de cifs, sino que también es técnicamente incorrecto: se establece condicionalmente en función de los sockets del usuario (=1) frente a los del kernel (=0). Y las implementaciones de net/ parecen basar sus operaciones de espacio de usuario frente a kernel en ello. p. ej., al cerrar el socket TCP, los temporizadores TCP no se borran porque sk->sk_net_refcnt=1: (cf. commit 151c9c724d05 ("tcp: finalizar correctamente los temporizadores para los sockets del kernel")) net/ipv4/tcp.c: void tcp_close(struct sock *sk, long timeout) { lock_sock(sk); __tcp_close(sk, timeout); release_sock(sk); if (!sk->sk_net_refcnt) inet_csk_clear_xmit_timers_sync(sk); sock_put(sk); } Esto arrojará una advertencia de lockdep y luego, como se esperaba, un bloqueo en tcp_write_timer(). Una forma de reproducir esto es ejecutando el reproductor desde ef7134c7fc48 y luego 'rmmod cifs'. Unos segundos más tarde, aparece la advertencia de bloqueo/lockdep. Solución: No deberíamos meternos con los componentes internos del socket nosotros mismos, así que no configure sk_net_refcnt manualmente. También cambie __sock_create() a sock_create_kern() para que sea más explícito. En cuanto a los espacios de nombres de red que no son init_net, lo tratamos de la mejor manera que podemos: mantenemos una referencia netns adicional para server->ssocket y la descartamos cuando se libera. Esto garantiza que netns siga existiendo siempre que necesitemos crear o destruir server->ssocket, pero no está directamente vinculado a él.
Impacto
Puntuación base 3.x
5.50
Gravedad 3.x
MEDIA