Vulnerabilidad en kernel de Linux (CVE-2025-21702)
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
18/02/2025
Última modificación:
13/03/2025
Descripción
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: pfifo_tail_enqueue: Descartar nuevo paquete cuando sch->limit == 0 Comportamiento esperado: En caso de que alcancemos el límite del planificador, pfifo_tail_enqueue() descartará un paquete en la cola del planificador y disminuirá el qlen del planificador en uno. Luego, pfifo_tail_enqueue() pone en cola un nuevo paquete y aumenta el qlen del planificador en uno. Finalmente, pfifo_tail_enqueue() devuelve el código de estado `NET_XMIT_CN`. Comportamiento extraño: En caso de que establezcamos `sch->limit == 0` y activemos pfifo_tail_enqueue() en un planificador que no tiene ningún paquete, el paso 'descartar un paquete' no hará nada. Esto significa que el qlen del planificador todavía tiene un valor igual a 0. Luego, continuamos poniendo en cola un nuevo paquete y aumentamos el qlen del planificador en uno. En resumen, podemos aprovechar pfifo_tail_enqueue() para aumentar qlen en uno y devolver el código de estado `NET_XMIT_CN`. El problema es: digamos que tenemos dos qdiscs: Qdisc_A y Qdisc_B. - El tipo de Qdisc_A debe tener la función '->graft()' para crear una relación padre/hijo. Digamos que el tipo de Qdisc_A es `hfsc`. Poner en cola un paquete en esta qdisc activará `hfsc_enqueue`. - El tipo de Qdisc_B es pfifo_head_drop. Poner en cola un paquete en esta qdisc activará `pfifo_tail_enqueue`. - Qdisc_B está configurado para tener `sch->limit == 0`. - Qdisc_A está configurado para enrutar el paquete en cola a Qdisc_B. Poner en cola un paquete a través de Qdisc_A conducirá a: - hfsc_enqueue(Qdisc_A) -> pfifo_tail_enqueue(Qdisc_B) - Qdisc_B->q.qlen += 1 - pfifo_tail_enqueue() devuelve `NET_XMIT_CN` - hfsc_enqueue() comprueba `NET_XMIT_SUCCESS` y ve `NET_XMIT_CN` => hfsc_enqueue() no aumenta el qlen de Qdisc_A. Todo el proceso conduce a una situación en la que Qdisc_A->q.qlen == 0 y Qdisc_B->q.qlen == 1. Reemplazar 'hfsc' por otro tipo (por ejemplo: 'drr') sigue conduciendo al mismo problema. Esto viola el diseño donde el qlen del padre debe ser igual a la suma del qlen de sus hijos. Impacto del error: este problema se puede utilizar para la escalada de privilegios de usuario a kernel cuando sea posible.
Impacto
Referencias a soluciones, herramientas e información
- https://git.kernel.org/stable/c/020ecb76812a0526f4130ab5aeb6dc7c773e7ab9
- https://git.kernel.org/stable/c/647cef20e649c576dff271e018d5d15d998b629d
- https://git.kernel.org/stable/c/78285b53266d6d51fa4ff504a23df03852eba84e
- https://git.kernel.org/stable/c/79a955ea4a2e5ddf4a36328959de0de496419888
- https://git.kernel.org/stable/c/7a9723ec27aff5674f1fd4934608937f1d650980
- https://git.kernel.org/stable/c/a56a6e8589a9b98d8171611fbcc1e45a15fd2455
- https://git.kernel.org/stable/c/b6a079c3b6f95378f26e2aeda520cb3176f7067b
- https://git.kernel.org/stable/c/e40cb34b7f247fe2e366fd192700d1b4f38196ca