{
 "finding_id": "DF-3487",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "leak",
 "confidence": "certain",
 "verdict": "Heap OOB read in ng_pppoe_rcvdata() PPPOE_PRIMED branch reproduced deterministically on the stock INVARIANTS kernel: a 32-byte PADI with ph->length=1024 and a Service-Name tag claiming 900 data bytes makes get_tag()/scan_tags() walk past the packet and make_packet() copy 896 bytes of out-of-bounds mbuf-zone memory into the emitted PADO, where the harness captures it. Leaked content includes kernel heap pointers (0xfffff80117632908 etc.), mbuf header fields, ifnet names and, on an active-traffic boot, a complete in-flight TCP segment. Identical 3/3 runs per boot, two boots. Same root cause class as DF-0414 but a distinct sink (PRIMED/daemon-echo path, not the ether-side discovery branch). Root cause is the missing ph->length-vs-packet-length check that the session branch (ng_pppoe.c:1632) already performs.",
 "exploit_chain": "",
 "evidence": [
  "findings/poc/DF-3487/run.log: PPSBX: PADI pre-send dump (m_len=32): ... 01 01 03 84 SERVNAME followed by captured 944-byte PADO",
  "findings/poc/DF-3487/leak1.txt: 944-byte capture; OOB window mbuf+32..mbuf+924 with sess_con pointer and .vn1 ifnet name",
  "findings/poc/DF-3487/leak_sample.txt: boot-A sample with kernel pointers 0xfffff80117632908/0xfffff80117632b08 and a full leaked TCP segment at PADO offset 0x210",
  "findings/poc/DF-3487/fixrun.log + fixleak1/2.txt: with fix.diff applied, ppsbx_len: 0 and empty capture on 2/2 runs, no crash"
 ],
 "poc_changes": "Harness authored fresh (no seed). Two iterations needed: (1) netgraph type must be registered before node creation (setup moved to first sysctl command); (2) tag type/length bytes must be written in big-endian wire order - an initial little-endian write made tag_len read as 0x8403 so get_tag correctly rejected it; after the byte-order fix the leak reproduced immediately.",
 "attempts": 5,
 "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": 1500,
 "guest_dirty": 0,
 "build_cmd": "cd /usr/src/sys/netgraph7/{netgraph,pppoe}: make obj depend && make; cd /root/ppsbx && make; kldload netgraph.ko ng_pppoe.ko ppsbx.ko",
 "run_cmd": "sysctl debug.ppsbx_cmd=1; sleep 1; sysctl debug.ppsbx_cmd=2; sysctl debug.ppsbx_len; sysctl -b debug.ppsbx_capture | od -A x -t x1",
 "code_hash": "f410d3f47b734a85393091e609820f7d344c1b2d44f7d8082bd58d922aa86272",
 "notes": "Verification side-quest: an initially-hypothesized integer overflow in ng_parse.c:1221 (foff = kmalloc(num*4)) was REFUTED live on this guest - on x86-64 sizeof() promotes the product to 64-bit so no wrap occurs; num=0x40000001 instead produced a ~4GB M_WAITOK kmalloc that wedged the guest into a pagedaemon death spiral (root-gated memory-exhaustion only, not filed). DF-0413 reachability evidence: NGM_ASCII2BINARY parses into a fixed 2000-byte buffer (ng_base.c:2458,2515) while sizedstring/string elements accept up to 64KB - the Info-rated latent finding is concretely reachable by the root ngctl user.",
 "recommended_fix": "In ng_pppoe_rcvdata() PRIMED branch, reject the PADI when m->m_pkthdr.len < sizeof(*wh) + ntohs(wh->ph.length), mirroring the session-branch check at ng_pppoe.c:1632 (see validated fix.diff).",
 "fix_status": "fixed",
 "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 (stock kernel; ng_pppoe.ko rebuilt from patched /usr/src - ng_pppoe is a KLD on this guest so the module is the executing code for this path)",
 "fix_baseline_reproduced": 1,
 "fix_patched_reproduced": 0,
 "fix_verdict": "fix.diff applied to guest /usr/src, ng_pppoe.ko rebuilt and reloaded on a fresh boot; identical PADI input produced no PADO (ppsbx_len 0 vs 944 baseline), empty capture, no panic, 2/2 runs. Full-kernel nativekernel rebuild unnecessary because the vulnerable code executes solely from the KLD.",
 "fix_evidence": [
  "findings/poc/DF-3487/fixrun.log",
  "findings/poc/DF-3487/fixleak1.txt",
  "findings/poc/DF-3487/fixleak2.txt",
  "findings/poc/DF-3487/fix.diff"
 ]
}