DF-3273 / verdict.json
{ "finding_id": "DF-3273", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "Unauthenticated PPP peer panics the kernel with ONE frame: LCP CONF-NAK with h->len=0 (ident 0 matches the initial confid, or is read off the wire). sppp_cp_input only re-validates len<4 for CONF_REQ; CONF_NAK/CONF_REJ are dispatched with len 0..3 to the RCN handlers, whose len -= 4; kmalloc(len, M_TEMP, M_INTWAIT) becomes kmalloc(0xFFFFFFFFFFFFFFFC). round_page() wraps the size to 0, the degenerate oversized allocation path corrupts the kernel map, and the kernel panics (vm_map_entry_link: dup addr map via kmem_slab_alloc <- _kmalloc). Deterministic across resets on the stock INVARIANTS guest. Same bug in all six RCN handlers (lcp/ipcp/ipv6cp x rej/nak). fix.diff adds the missing len<4 guard to the CONF_NAK/CONF_REJ arm; validated: frame rejected, no panic, LCP still negotiates.", "exploit_chain": "single 8-byte frame ff03c021 03 00 0000 -> negative-length kmalloc -> allocator panic (remote DoS; no memory-control primitive)", "evidence": [ "findings/poc/DF-3273/panic.txt: panic: vm_map_entry_link: dup addr map ... kmem_slab_alloc+0x145 <- _kmalloc+0x5be, captured from the serial console of the baseline run", "findings/poc/DF-3273/VERDICT.md: full path trace incl. round_page wrap" ], "kernel_refs": [ "sys/net/sppp/if_spppsubr.c:1412", "sys/net/sppp/if_spppsubr.c:1417", "sys/net/sppp/if_spppsubr.c:1541", "sys/net/sppp/if_spppsubr.c:2492", "sys/kern/kern_slaballoc.c:942", "sys/kern/kern_slaballoc.c:1706" ], "poc_changes": "Standalone C trigger only (8-byte frame write to the harness device); no fixes needed beyond the harness itself (see DF-3272 pack).", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 300, "guest_dirty": 0, "build_cmd": "cd /root/poc && make && cc -O2 -o poc_3273 poc_3273.c (fix build: cd /usr/src/sys/net/sppp && make)", "run_cmd": "kldload /root/poc/sppp_harness.ko && /root/poc/poc_3273", "code_hash": "d1d767baaf493e6985d413b67dedcf2855d0873e982b5cf3ce91908a672837e5", "notes": "Legacy (PPP) bucket. Panic fires inside the allocation itself on the INVARIANTS kernel; on non-INVARIANTS builds the degenerate chunk pointer reaches kfree and trips z_Magic checks / faults on unmapped kernel_map space -- fatal either way. reachability requires only that a sppp interface exists (any netgraph7/ng_sppp or sync-serial driver attach).", "recommended_fix": "Add the missing len<4 guard to the CONF_NAK/CONF_REJ arm of sppp_cp_input (mirroring the CONF_REQ guard at if_spppsubr.c:1417).", "fix_status": "fixed", "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 (sppp.ko rebuilt from patched /usr/src/sys/net/sppp, cc 8.3 -Werror clean)", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Patched sppp.ko: poc_3273 injects the same frame, write() returns 8, kernel stays up (frame dropped as ierror); DF-3272 driver on the same patched module completes a normal LCP negotiation, so no regression.", "fix_evidence": [ "findings/poc/DF-3273/panic.txt (baseline)", "findings/poc/DF-3273/fix.diff", "DF-3272 pack run.fixed.log (same patched module, negotiation healthy)" ] } |