β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-3489

HOST_UNIQ tag broadcasts sess_con kernel heap pointer on the wire to unauthenticated LAN peers

Summary

pppoe_start() and the PRIMED branch set uniqtag.data.pointer = sp - the raw sess_con heap pointer - into the PTT_HOST_UNIQ/PTT_AC_COOKIE tag that is broadcast in every PADI/PADO (and echoed in PADR/PADS) to the local Ethernet segment. Any unauthenticated LAN observer of the (broadcast) discovery exchange learns a live kernel heap address (PoC capture: 0xfffff8008976ba80). By protocol design the tag is echoed, but the pointer value itself defeats KASLR-style randomization and gives heap-layout reconnaissance for follow-on corruption bugs. Passive listener on the LAN segment; no direct memory access. Fix: random 64-bit cookie with indexed lookup instead of the pointer (FreeBSD's host-uniq hardening). [VERIFIED pass2: reproduced - PADI broadcast carries HOST_UNIQ 0xfffff8008974ba80 a live kernel heap pointer; karc4random cookie fix A/B on rebuilt kernel]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3489 Β· 7 files
FileTypeDescriptionSize
README.md β€” 397 B ↓ raw
VERDICT.md β€” 2.0 KB ↓ raw
env.txt β€” 329 B view raw
fix.diff β€” 1.5 KB view raw
manifest.json β€” 700 B view raw
run.log β€” 598 B view raw
verdict.json β€” 2.4 KB view raw

DF-3489 - PADI HOST_UNIQ broadcasts kernel heap pointer

Harness kernel. gcc -O -o ppptest ppptest.c; ./ppptest. Baseline: HOST_UNIQ tag bytes = 0xfffff8008974ba80 (kernel pointer). Fixed kernel (fix.diff): random cookie edf6485b58d4a50b. A/B validated.

Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Sun Oct 25 20:46:48 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_NG7 x86_64 (harness kernel)

VERDICT.md
↓ download raw

DF-3489 - VERDICT

status: reproduced | reproduced: 1 | impact: leak | confidence: certain

Reproduced on the harness kernel (NETGRAPH7_PPPOE; ng7 is not in the stock kernel - harness required, per DF-2539 rig convention). ppptest.c builds the graph my-node --c0--> pppoe:session0 plus my-node e0 <--> pppoe:ethernet with a data socket associated to the node, sends NGM_PPPOE_CONNECT, and reads the emitted PADI directly off the ethernet hook. The captured PADI (40 bytes) contains tag 0x0103 PTT_HOST_UNIQ len=8 value bytes 80 ba 74 89 00 f8 ff ff = 0xfffff8008974ba80 little-endian - a live kernel direct-map heap pointer (ng_pppoe.c:1071 'uniqtag.data.pointer = sp;' and the PRIMED twin at :1228). Every PADI/PADO is broadcast on the segment, so any unauthenticated LAN observer harvests a kernel heap address (KASLR-style defeat / heap-layout reconnaissance). FIX VALIDATED A/B: with fix.diff applied (random karc4random64 cookie per session + cookie-based finduniq), the identical test on the rebuilt kernel emits ed f6 48 5b 58 d4 a5 0b - a random cookie, no kernel pointer - while the session machinery still produces the same PADI.

Kernel references

Exploit chain

passive LAN sniffer -> broadcast PADI -> HOST_UNIQ tag = kernel heap pointer; value feeds heap-grooming for any follow-on corruption bug

Evidence

run.log (PADI hexdump with 0103/8/80ba748900f8ffff and the fixed-kernel rerun 0edf6485b58d4a50b), ppptest.c, fix.diff, padi.pcap path

random 64-bit per-session HOST_UNIQ cookie with cookie-based session lookup (see fix.diff).

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
↓ fix.diffper-fix-DF-3489

Confirmed kernel references

Detail

Exploit chain

passive LAN sniffer -> broadcast PADI -> HOST_UNIQ tag = kernel heap pointer; value feeds heap-grooming for any follow-on corruption bug

Evidence (decisive lines)

run.log (PADI hexdump with 0103/8/80ba748900f8ffff and the fixed-kernel rerun 0edf6485b58d4a50b), ppptest.c, fix.diff, padi.pcap path

PoC changes

ppptest.c written fresh (ng7 wire format; graph includes data-socket association to capture frames without touching the real NIC)

Verified recommended fix

random 64-bit per-session HOST_UNIQ cookie with cookie-based session lookup (see fix.diff).

Verdict

Reproduced on the harness kernel (NETGRAPH7_PPPOE; ng7 is not in the stock kernel - harness required, per DF-2539 rig convention). ppptest.c builds the graph my-node --c0--> pppoe:session0 plus my-node e0 <--> pppoe:ethernet with a data socket associated to the node, sends NGM_PPPOE_CONNECT, and reads the emitted PADI directly off the ethernet hook. The captured PADI (40 bytes) contains tag 0x0103 PTT_HOST_UNIQ len=8 value bytes 80 ba 74 89 00 f8 ff ff = 0xfffff8008974ba80 little-endian - a live kernel direct-map heap pointer (ng_pppoe.c:1071 'uniqtag.data.pointer = sp;' and the PRIMED twin at :1228). Every PADI/PADO is broadcast on the segment, so any unauthenticated LAN observer harvests a kernel heap address (KASLR-style defeat / heap-layout reconnaissance). FIX VALIDATED A/B: with fix.diff applied (random karc4random64 cookie per session + cookie-based finduniq), the identical test on the rebuilt kernel emits ed f6 48 5b 58 d4 a5 0b - a random cookie, no kernel pointer - while the session machinery still produces the same PADI.