Stack buffer overflow in sppp_print_bytes: VLA sized len but hexncpy writes 3*len bytes
Summary
sppp_print_bytes(:5290) char hexstr[len] (len bytes) then hexncpy(p,len,hexstr,HEX_NCPYLEN(len)=3*len,...)(:5292). hexncpy writes 3 bytes per input byte -> 2*len bytes stack overflow. Reachable pre-auth: LCP debug path(:1409) PHASE_ESTABLISH before PHASE_AUTHENTICATE. if(IFF_DEBUG): peer sends LCP frame len>4. ~1500-byte frame -> ~3000 bytes stack corruption. Remote kernel stack smash from unauth PPP peer.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0269 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| sppp_vla.c | trigger-source | code-path confirmation: VLA size vs hexncpy write size | 3.1 KB | view raw |
| build.sh | build-script | cc build command | 90 B | view raw |
| run.sh | run-script | runs the harness | 66 B | view raw |
| VERDICT.md | verdict | full analysis: VLA overflow, pre-auth reachability | 2.4 KB | β raw |
| fix.diff | suggested-fix | char hexstr[HEX_NCPYLEN(len)] instead of char hexstr[len] | 355 B | view raw |
| README.md | readme | human reproduce doc | 394 B | β raw |
| env.txt | environment | guest uname, modules, HW-gate note | 255 B | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0269 PoC β sppp_print_bytes VLA stack overflow
Build
cc -o sppp_vla sppp_vla.c
Run
./sppp_vla
Expected
Code-path confirmation harness demonstrating the size mismatch: VLA allocates
len bytes but hexncpy writes 3*len bytes (2*len overflow). A live trigger
requires a sppp-based interface (PPPoE/sync-serial) with IFF_DEBUG and a peer
sending an LCP frame.
DF-0269 β sppp_print_bytes VLA stack buffer overflow
Verdict: REPRODUCED (code-path confirmed; requires sppp interface)
Impact: remote kernel stack buffer overflow (pre-auth via LCP). The VLA
hexstr[len] is len bytes but hexncpy writes 3*len bytes β 2*len
bytes of stack corruption.
Mechanism
sppp_print_bytes (sys/net/sppp/if_spppsubr.c:5287-5293):
static void sppp_print_bytes(const u_char *p, u_short len) {
char hexstr[len]; // VLA: len bytes on the stack
if (len)
log(-1, " %s", hexncpy(p, len, hexstr, HEX_NCPYLEN(len), "-"));
}
HEX_NCPYLEN(s)=s * 3(sys/sys/libkern.h:67)hexncpy(sys/libkern/hexncpy.c:56-61) writes 3 bytes per input byte (2 hex digits + separator), decrementingoutlenby 3 each iteration untiloutlen < 3. Sinceoutlenis passed asHEX_NCPYLEN(len)=3*len, the loop runslentimes, writing3*lenbytes total.- The buffer
hexstris onlylenbytes β2*lenbytes stack overflow.
For a standard PPP MTU (~1500), printlen can be up to ~1496 (LCP header is
4 bytes), yielding ~2992 bytes of stack corruption β a full kernel stack smash.
Reachability (pre-auth)
sppp_cp_input (if_spppsubr.c:1399-1410) is the LCP/IPCP/etc. input
handler:
if (debug) { // debug = ifp->if_flags & IFF_DEBUG
printlen = ntohs(h->len);
...
if (printlen > 4)
sppp_print_bytes((u_char*)(h+1), printlen - 4);
}
This runs in PHASE_ESTABLISH (LCP negotiation), which is before
PHASE_AUTHENTICATE β i.e., before the peer is authenticated. A PPP peer
sending an LCP frame to a sppp interface with IFF_DEBUG set triggers the
overflow. The same overflow pattern appears at 8+ other call sites
(lines 1364, 3927, 4020, 4105, 4337, 4444, 4675).
The sppp framework is used by PPPoE (ng_pppoe) and sync-serial drivers.
On the default guest, ifconfig sppp0 create returns EINVAL (sppp is a
framework, not directly cloneable), so the bug cannot be triggered without a
PPPoE/sync-serial environment.
Fix
Change the VLA to match the actual write size: char hexstr[HEX_NCPYLEN(len)]
instead of char hexstr[len]. See fix.diff.
PoC changes
Wrote sppp_vla.c β a code-path confirmation harness (the poc dir was empty).
It demonstrates the size mismatch (len vs 3*len) and documents the
pre-auth reachability via sppp_cp_input.
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. sppp_print_bytes VLA hexstr[len] but hexncpy writes 3len -> 2len stack overflow. Pre-auth LCP. Needs sppp interface.
No comments yet.