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

Vulnerabilidad en kernel de Linux (CVE-2024-56687)

Gravedad CVSS v3.1:
MEDIA
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
28/12/2024
Última modificación:
31/01/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: usb: musb: Reparar bloqueo de hardware en la primera solicitud de endpoint Rx Existe la posibilidad de que la devolución de llamada de una solicitud pueda invocarse desde usb_ep_queue() (rastreo de llamada a continuación, complementado con llamadas faltantes): req->complete desde usb_gadget_giveback_request (drivers/usb/gadget/udc/core.c:999) usb_gadget_giveback_request desde musb_g_giveback (drivers/usb/musb/musb_gadget.c:147) musb_g_giveback desde rxstate (drivers/usb/musb/musb_gadget.c:784) rxstate desde musb_ep_restart (drivers/usb/musb/musb_gadget.c:1169) musb_ep_restart desde Según la cadena de documentación de usb_ep_queue(), esto no debería suceder: "Tenga en cuenta que la devolución de llamada ->complete() de @req nunca debe llamarse desde usb_ep_queue() ya que eso puede crear situaciones de bloqueo". De hecho, un bloqueo de hardware podría ocurrir en la siguiente secuencia: 1. El gadget se inicializa usando musb_gadget_enable(). 2. Mientras tanto, llega un paquete y se activa el indicador RXPKTRDY, lo que genera una interrupción. 3. Si las IRQ están habilitadas, se gestiona la interrupción, pero musb_g_rx() encuentra una cola vacía (next_request() devuelve NULL). El indicador de interrupción ya ha sido borrado por el controlador de la capa de pegamento, pero el indicador RXPKTRDY permanece activado. 4. La primera solicitud se pone en cola usando usb_ep_queue(), lo que lleva a la llamada de req->complete(), como se muestra en el seguimiento de la llamada anterior. 5. Si la devolución de llamada habilita las IRQ y hay otro paquete en espera, se repite el paso (3). La cola de solicitudes está vacía porque usb_g_giveback() elimina la solicitud antes de invocar la devolución de llamada. 6. El endpoint permanece bloqueado, ya que se ha gestionado la interrupción provocada por la configuración del hardware del indicador RXPKTRDY, pero el indicador en sí permanece configurado. Para que se produzca este escenario, solo es necesario que las IRQ se habiliten en algún momento durante la devolución de llamada completa. Esto sucede con el dispositivo USB Ethernet, cuya devolución de llamada rx_complete() llama a netif_rx(). Si se llama en el contexto de la tarea, netif_rx() deshabilita las mitades inferiores (BH). Cuando se vuelven a habilitar las BH, también se habilitan las IRQ para permitir que se procesen las IRQ suaves. El dispositivo en sí se inicializa en la carga del módulo (o en el arranque si está integrado), pero la primera solicitud se pone en cola cuando se activa la interfaz de red, lo que activa rx_complete() en el contexto de la tarea a través de ioctl(). Si llega un paquete mientras la interfaz está inactiva, puede impedir que la interfaz reciba más paquetes del host USB. La situación es bastante complicada con muchas partes involucradas. Este problema en particular se puede resolver de varias maneras posibles: 1. Asegúrese de que las devoluciones de llamadas nunca habiliten las IRQ. Esto sería difícil de hacer cumplir, ya que descubrir cómo interactúa netif_rx() con las interrupciones ya era bastante desafiante y u_ether no es el único controlador de función. También podrían estar ocultos "errores" similares en otros controladores. 2. Desactive las interrupciones MUSB en musb_g_giveback() antes de llamar a la devolución de llamada y vuelva a habilitarlas después (llamando a musb_{dis,en}able_interrupts(), por ejemplo). Esto garantizaría que las interrupciones MUSB no se gestionen durante la devolución de llamada, incluso si las IRQ están habilitadas. De hecho, permitiría que las IRQ se habiliten al liberar el bloqueo. Sin embargo, esto parece un truco poco elegante. 3. Modifique el controlador de interrupciones para borrar el indicador RXPKTRDY si la cola de solicitudes está vacía. Si bien este enfoque también parece un truco, desperdicia tiempo de CPU al intentar gestionar paquetes entrantes cuando el software no está listo para procesarlos. ---trunqué---

Productos y versiones vulnerables

CPE Desde Hasta
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.18 (incluyendo) 6.1.120 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (incluyendo) 6.6.64 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (incluyendo) 6.11.11 (excluyendo)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.12 (incluyendo) 6.12.2 (excluyendo)