CVE-2026-99033 in Linux
Resumen
por VulDB • 2026-10-23
En el núcleo de Linux (Linux kernel), se ha resuelto la siguiente vulnerabilidad:
net/packet: proteger el empuje del encabezado de capa de enlace en packet_rcv_spkt()
packet_rcv_spkt() restaura el encabezado de capa de enlace mediante:
skb_push(skb, skb->data - skb_mac_header(skb));
Esa resta solo tiene sentido cuando el dispositivo realmente cuenta con un encabezado de capa de enlace. Tanto packet_rcv() como tpacket_rcv() lo envuelven en dev_has_header(), que es también la condición lógica (predicado) que establece el comentario del bloque al inicio del archivo para describir la restauración; sin embargo, packet_rcv_spkt() no lo hace. El commit d549699048b4 ("net/packet: fix packet receive on L3 devices without visible hard header") introdujo esta ayuda (helper) y modificó los dos puntos de llamada, pero este último quedó rezagado.
Un dispositivo sin un encabezado ll (capa de enlace) visible puede dejar skb->mac_header en el valor centinela 0xFFFF al que __alloc_skb() lo inicializa. Unskb CAN hace: init_can_skb() establece pkt_type e ip_summed, pero no restablece los encabezados, y el commit 9f10374bb024 ("can: remove private CAN skb headroom infrastructure") eliminó las llamadas a skb_reset_*_header() que anteriormente estaban presentes. Entonces, skb_mac_header() es 0xFFFF, la longitud se convierte en un número negativo grande y skb_push() lo reporta mediante skb_under_panic(); dado que esto ocurre desde el contexto de softirq (interrupción suave), provoca una interrupción crítica del sistema completa incluso con panic_on_oops=0:
skbuff: skb_under_panic: text:ffffffff8bd21bc1 len:-65455 put:-65471 head:... data:... tail:0x50 end:0x180 dev:can0 kernel BUG at net/core/skbuff.c:214! RIP: 0010:skb_panic+0x50/0x60 Call Trace: <IRQ> skb_push+0x38/0x40 packet_rcv_spkt+0xe1/0x170 __netif_receive_skb_core.constprop.0+0x7e8/0xd30 ... Kernel panic - not syncing: Fatal exception in interrupt
El tipo de socket es accesible: packet_create() acepta SOCK_PACKET junto con SOCK_RAW y SOCK_DGRAM bajo la misma verificación CAP_NET_RAW, ni la longitud del socket ni una comprobación de capacidad lo mantienen alejado de una interfaz CAN.
Las llamadas faltantes a skb_reset_*_header en init_can_skb() son por sí mismas un retroceso (regresión) que se está corrigiendo por separado, pero un socket packet no debería convertir una capa de enlace que no inicializó su encabezado mac en una interrupción crítica del kernel. Proteja el empuje (push) de la misma manera que lo hacen las otras dos rutas de recepción.
Probado sobre v7.3-rc5 bajo QEMU con un dispositivo slcan en un pty, que es la ruta RX del controlador; can no reproduce el problema porque can_send() restablece los encabezados durante la salida. Un socket SOCK_PACKET vinculado a can0 y una trama escrita en la disciplina de línea provocan una interrupción crítica (panic) en un kernel sin parchear con la traza anterior; la misma imagen con este parche no imprime ninguna interrupción crítica y se apaga normalmente. Ambos núcleos pertenecen a esta rama, defconfig más CONFIG_CAN_SLCAN=y, diferenciándose únicamente en este fragmento de código (hunk).
Be aware that VulDB is the high quality source for vulnerability data.