
Repositorio de investigación para CVE-2026-68121, un use-after-free en PPPoE del kernel de Linux en pppoe_sendmsg() que permite escalada local de privilegios, con PoC, análisis de causa raíz y configuración de laboratorio.
PPPoEject
Una vulnerabilidad de corrupción de memoria del kernel de Linux en la ruta de transmisión de PPPoE,
causada por un puntero obsoleto a una cabecera sk_buff después de que un callback de cabecera de dispositivo
reasigne la cabecera del skb.
Este repositorio está destinado únicamente a la investigación de seguridad autorizada, al análisis de vulnerabilidades del kernel, a entornos CTF y a pruebas defensivas.
No ejecute código de prueba de concepto contra sistemas sin autorización explícita.
| Campo | Detalles |
|---|---|
| CVE | CVE-2026-68121 |
| Nombre en clave | PPPoEject |
| Componente | Linux Kernel |
| Subsistema | PPPoE / Networking |
| Archivo afectado | drivers/net/ppp/pppoe.c |
| Función principal | pppoe_sendmsg() |
| Clase de error | Use-After-Free |
| Impacto | Corrupción de memoria del kernel |
| Impacto potencial | Escalada de privilegios local |
| CVSS v3.1 | 7.8 — Alta |
| Vector de ataque | Local |
| Complejidad del ataque | Baja |
| Privilegios requeridos | Bajos |
| Interacción del usuario | Ninguna |
| Estado | Parcheado |
El registro CVE identifica la vulnerabilidad como un puntero de cabecera PPPoE obsoleto que
puede volverse inválido cuando dev_hard_header() reasigna la cabecera del skb.
La vulnerabilidad existe en:
drivers/net/ppp/pppoe.c
dentro de:
pppoe_sendmsg()
La secuencia vulnerable es conceptualmente:
pppoe_sendmsg()
│
▼
Save PPPoE header pointer
│
▼
dev_hard_header()
│
▼
skb head may be reallocated
│
▼
Old pointer becomes stale
│
▼
PPPoE writes through stale pointer
│
▼
Use-After-Free
│
▼
Kernel memory corruption
El código de red de Linux permite que los callbacks de encabezado de dispositivo reasignen la cabeza del sk_buff. Por lo tanto, un puntero a la cabeza antigua no puede reutilizarse de forma segura después de que dev_hard_header() retorne.
El problema central es una violación de tiempo de vida.
pppoe_sendmsg() obtiene un puntero al encabezado PPPoE antes de invocar:
dev_hard_header()
Sin embargo, esa callback puede provocar que la cabeza del skb se mueva.
Conceptualmente:
Before callback:
skb
┌──────────────────────────────┐
│ Ethernet │ PPPoE │ Payload │
└──────────┴───────┴───────────┘
▲
│
stale pointer
After skb expansion:
old skb head ──X──► freed
new skb head
┌────────────────────────────────────┐
│ Ethernet │ PPPoE │ Payload │
└──────────┴───────┴─────────────────┘
▲
│
valid location
El puntero antiguo sigue haciendo referencia a la asignación liberada.
Cuando PPPoE posteriormente escribe la cabecera a través de ese puntero, el kernel realiza una escritura use-after-free.
El disparador documentado implica una condición de carrera en torno a copy_from_user() y cambios
en las operaciones de cabecera de un dispositivo team.
Una secuencia descrita es:
PPPoE sendmsg()
│
▼
copy_from_user() blocks
│
│
├───────────────┐
│ │
▼ ▼
Team device changes First non-Ethernet
header operations port is added
│
▼
Delegated GRE callback
│
▼
skb head expansion
│ │
└───────────────┘
│
▼
stale PPPoE pointer
│
▼
use-after-free write
El registro CVE señala que esto puede ocurrir cuando el primer puerto no Ethernet se añade a un dispositivo team vacío y la callback del encabezado GRE delegada expande la cabeza del skb.
La vulnerabilidad puede provocar:
El vector CVSS publicado del CVE es:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
con una puntuación base de 7.8 Alta.
Los componentes relevantes son:
PF_PPPOX / PPPoE socket
│
▼
pppoe_sendmsg()
│
▼
sk_buff (skb)
│
▼
dev_hard_header()
│
▼
Network device header callback
│
▼
Potential skb head expansion
│
▼
PPPoE stale header pointer
│
▼
UAF write
El código vulnerable, por lo tanto, no es simplemente un analizador genérico de paquetes PPPoE; la condición crítica es la interacción entre la transmisión de sockets PPPoE y la reasignación dinámica de la cabecera skb.
La corrección upstream se titula:
pppoe: reload header pointer after dev_hard_header()
La corrección recarga el encabezado PPPoE a través del desplazamiento del encabezado de red del skb después de la creación del encabezado del dispositivo.
La propiedad importante es:
Before:
header pointer
│
▼
dev_hard_header()
│
▼
skb moves
│
▼
pointer = stale ❌
After:
dev_hard_header()
│
▼
skb may move
│
▼
reload header using skb offset
│
▼
pointer = valid ✅
pskb_expand_head() actualiza el desplazamiento relevante del skb cuando la cabeza del skb se reubica, lo que hace que la búsqueda basada en desplazamiento sea segura tras la reasignación.