
Research repository for CVE-2026-68121, a Linux kernel PPPoE use-after-free in pppoe_sendmsg() enabling local privilege escalation, with PoC, root-cause analysis, and lab setup.
PPPoEject
A Linux kernel memory-corruption vulnerability in the PPPoE transmit path,
caused by a stale pointer to an sk_buff header after a device header callback
reallocates the skb head.
This repository is intended for authorized security research, kernel vulnerability analysis, CTF environments, and defensive testing only.
Do not execute proof-of-concept code against systems without explicit authorization.
| Field | Details |
|---|---|
| CVE | CVE-2026-68121 |
| Codename | PPPoEject |
| Component | Linux Kernel |
| Subsystem | PPPoE / Networking |
| Affected File | drivers/net/ppp/pppoe.c |
| Primary Function | pppoe_sendmsg() |
| Bug Class | Use-After-Free |
| Impact | Kernel memory corruption |
| Potential Impact | Local Privilege Escalation |
| CVSS v3.1 | 7.8 β High |
| Attack Vector | Local |
| Attack Complexity | Low |
| Privileges Required | Low |
| User Interaction | None |
| Status | Patched |
The CVE record identifies the vulnerability as a stale PPPoE header pointer that
can become invalid when dev_hard_header() reallocates the skb head.
The vulnerability exists in:
drivers/net/ppp/pppoe.c
within:
pppoe_sendmsg()
The vulnerable sequence is conceptually:
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
Linux networking code allows device header callbacks to reallocate the
sk_buff head. A pointer into the old head therefore cannot safely be reused
after dev_hard_header() returns.
The core issue is a lifetime violation.
pppoe_sendmsg() obtains a pointer to the PPPoE header before invoking:
dev_hard_header()
However, that callback can cause the skb head to move.
Conceptually:
Before callback:
skb
ββββββββββββββββββββββββββββββββ
β Ethernet β PPPoE β Payload β
ββββββββββββ΄ββββββββ΄ββββββββββββ
β²
β
stale pointer
After skb expansion:
old skb head ββXβββΊ freed
new skb head
ββββββββββββββββββββββββββββββββββββββ
β Ethernet β PPPoE β Payload β
ββββββββββββ΄ββββββββ΄ββββββββββββββββββ
β²
β
valid location
The old pointer still references the freed allocation.
When PPPoE subsequently writes the header through that pointer, the kernel performs a use-after-free write.
The documented trigger involves a race around copy_from_user() and changes
to a team device's header operations.
One described sequence is:
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
The CVE record notes that this can occur when the first non-Ethernet port is added to an empty team device and the delegated GRE header callback expands the skb head.
The vulnerability can result in:
The CVE's published CVSS vector is:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
with a base score of 7.8 High.
The relevant components are:
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
The vulnerable code is therefore not simply a generic PPPoE packet parser; the critical condition is the interaction between PPPoE socket transmission and dynamic skb head reallocation.
The upstream fix is titled:
pppoe: reload header pointer after dev_hard_header()
The fix reloads the PPPoE header through the skb's network-header offset after device header creation.
The important property is:
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() updates the relevant skb offset when the skb head is
relocated, making the offset-based lookup safe after reallocation.
| Security Property | Vulnerable | Patched |
|---|---|---|
| Header pointer saved before callback | β | β |
| skb head can move | β | β |
| Pointer refreshed after callback | β | β |
| Stale pointer dereference | Possible | Prevented |
| Use-after-free write | Possible | Mitigated |
| Kernel memory corruption | Possible | Mitigated |
A controlled laboratory can be structured as: