Vulnerabilidad en kernel de Linux (CVE-2024-56644)
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
27/12/2024
Última modificación:
27/12/2024
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: net/ipv6: liberación de la excepción dst expirada almacenada en caché en el socket. Los objetos Dst se filtran en ip6_negative_advice() cuando se ejecuta esta función para una ruta IPv6 expirada ubicada en la tabla de excepciones. Hay varias condiciones que deben cumplirse para que se produzca la fuga: * se recibe un paquete ICMPv6 que indica un cambio de la MTU para la ruta, lo que da como resultado la creación de un dst de excepción * una conexión TCP que utiliza el dst de excepción para enrutar paquetes debe comenzar a agotar el tiempo de espera para que TCP comience las retransmisiones * después de que el dst de excepción caduque, el recolector de basura FIB6 no debe ejecutarse antes de que TCP ejecute ip6_negative_advice() para el dst de excepción caducado Cuando TCP ejecuta ip6_negative_advice() para un dst de excepción que ha caducado y si ningún otro socket tiene una referencia al dst de excepción, el recuento de referencias del dst de excepción es 2, que corresponde al incremento realizado por dst_init() y el incremento realizado por el socket TCP para el que se agota el tiempo de espera de la conexión. El recuento de referencias realizado por el socket nunca se libera. El recuento de referencias del dst se reduce en sk_dst_reset() pero esa reducción se contrarresta con un dst_hold() colocado intencionalmente justo antes del sk_dst_reset() en ip6_negative_advice(). Después de que ip6_negative_advice() haya terminado, no hay otro objeto vinculado al dst. El socket perdió su referencia almacenada en sk_dst_cache y el dst ya no está en la tabla de excepciones. El dst de excepción se convierte en un objeto filtrado. Como resultado de esta filtración de dst, se informa un recuento de referencias desequilibrado para el dispositivo de bucle invertido de un espacio de nombres de red que se destruye en núcleos que no contienen e5f80fcf869a ("ipv6: dar un dev IPv6 a blackhole_netdev"): unregister_netdevice: esperando a que lo se libere. Recuento de uso = 2 Corrija la filtración de dst eliminando dst_hold() en ip6_negative_advice(). El parche que introdujo dst_hold() en ip6_negative_advice() fue 92f1655aa2b22 ("net: fix __dst_negative_advice() race"). Pero 92f1655aa2b22 simplemente refactorizó el código con respecto al recuento de referencias dst, por lo que el problema estaba presente incluso antes de 92f1655aa2b22. El error se introdujo en 54c1a859efd9f ("ipv6: Don't drop cache route entry sometimes expired.") donde la ruta en caché expirada se elimina y el miembro sk_dst_cache del socket se establece en NULL al llamar a dst_negative_advice(), pero el recuento de referencias que pertenece al socket se deja desequilibrado. La versión IPv4 - ipv4_negative_advice() - no se ve afectada por este error. Cuando se agota el tiempo de conexión TCP, ipv4_negative_advice() simplemente restablece el sk_dst_cache del socket mientras disminuye el recuento de referencias del dst de excepción.
Impacto
Referencias a soluciones, herramientas e información
- https://git.kernel.org/stable/c/0b8903e6c881f72c6849d4952de742c656eb5ab9
- https://git.kernel.org/stable/c/3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045
- https://git.kernel.org/stable/c/535add1e9f274502209cb997801208bbe1ae6c6f
- https://git.kernel.org/stable/c/8b591bd522b71c42a82898290e35d32b482047e4
- https://git.kernel.org/stable/c/a95808252e8acc0123bacd2dff8b9af10bc145b7
- https://git.kernel.org/stable/c/b90d061345bb8cd51fece561a800bae1c95448a6
- https://git.kernel.org/stable/c/f43d12fd0fa8ee5b9caf8a3927e10d06431764d2