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

Raw sess_con kernel heap pointer broadcast on the LAN in PADI HOST_UNIQ / PADO AC_COOKIE tags (DF-3489 twin)

Summary

pppoe_start() sets uniqtag.data.pointer = sp into the PTT_HOST_UNIQ tag of every broadcast PADI, and the PRIMED branch sets the same pointer into the PTT_AC_COOKIE tag of every PADO; peers echo both tags by design. Any passive LAN observer of the (broadcast) discovery exchange learns a live direct-map kernel heap address (captured: 0xfffff8008d9e46f0, 3/3 rounds - side artifact of the verified DF-3491 run, leak_sample.txt). KASLR-style heap-layout defeat and slab reconnaissance for companion bugs. Fix: random 64-bit cookie + indexed lookup (FreeBSD host_uniq hardening).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3493 Β· 4 files
FileTypeDescriptionSize
README.md β€” 1.9 KB ↓ raw
leak_sample.txt β€” 593 B view raw
manifest.json β€” 777 B view raw
verdict.json β€” 2.2 KB view raw

DF-3493 β€” v1 ng_pppoe broadcasts the raw sess_con kernel heap pointer

in PADI/PADO discovery frames (DF-3489 twin)

File: sys/netgraph/pppoe/ng_pppoe.c (live stack)

Root cause

  • pppoe_start() client path (:812-835): uniqtag.data.pointer = sp; (:829) stuffed into a PTT_HOST_UNIQ tag that is broadcast in every PADI (:831-834, eh_prototype dst = ff:ff:ff:ff:ff:ff, :168-171).
  • PRIMED/server path (:1297-1359): uniqtag.data.pointer = sp; (:1337) into a PTT_AC_COOKIE tag emitted in every PADO (:1355-1358).
  • By protocol design both tags are echoed back by peers (PADO/PADR/PADS echo HOST_UNIQ / AC_COOKIE β€” :1039, :1108), so the pointer value is also present in unicast responses.

Any unauthenticated LAN observer of the (broadcast) discovery exchange learns a live struct sess_con heap address (direct-map VA), defeating KASLR-style heap randomization and providing slab reconnaissance for follow-on corruption bugs (e.g. DF-3491's OOB walk, DF-0457's leak).

Evidence (reproduced as a side artifact of the DF-3491 run)

The DF-3491 harness (../DF-3491/ppdprimed.c) captures the emitted PADO; its AC-COOKIE tag (wire type 0x0104) is the raw pointer:

    tag wire-type=0x0104 len=8
    [DF-3493] AC-COOKIE = raw kernel sess_con pointer 0xfffff8008d9e46f0

(../DF-3491/run.2.log, 3/3 rounds; ../DF-3491/run.log: 0xfffff8008d9e65e0. Raw bytes at PADO offset 0x3a5: f0 46 9e 8d 00 f8 ff ff.) leak_sample.txt holds the annotated hex.

Fix (as FreeBSD's host_uniq hardening / ng7 DF-3489)

Replace the pointer with a random 64-bit cookie plus an indexed lookup (hash table cookie→sess_con) so the on-wire value carries no address information.

Reproduce

Same harness as DF-3491: kldload ng_socket ng_pppoe; ./ppdprimed β€” the AC-COOKIE line prints the pointer every round. (The client-side PADI broadcast pointer at :829 is the same pattern; DF-3491's harness exercises the server branch.)

Fix verification

not_testable
per-fix-DF-3493

Confirmed kernel references

Detail

Exploit chain

passive listener on LAN segment captures broadcast PADI/PADO -> extracts sess_con pointer -> heap layout knowledge feeds exploitation of memory-corruption bugs in the same zone

Evidence (decisive lines)

leak_sample.txt (annotated raw bytes); ../DF-3491/run.2.log ('[DF-3493] AC-COOKIE = ... 0xfffff8008d9e46f0' 3/3); ../DF-3491/run.log (0xfffff8008d9e65e0)

PoC changes

No dedicated harness needed: the DF-3491 PADO capture carries the AC_COOKIE; PoC prints it directly.

Verified recommended fix

Replace the pointer with a random 64-bit cookie and an indexed (hash) lookup cookie->sess_con, as in FreeBSD's host_uniq hardening

Verdict

v1 ng_pppoe puts the raw struct sess_con heap pointer on the wire: pppoe_start() :829 (PTT_HOST_UNIQ in the broadcast PADI, eh_prototype dst ff:ff:ff:ff:ff:ff at :168-171) and the PRIMED branch :1337 (PTT_AC_COOKIE in every PADO), with peers echoing both tags by design (:1039, :1108). Reproduced as a side artifact of the DF-3491 run: the captured PADO's AC-COOKIE = 0xfffff8008d9e46f0 / 0xfffff8008d9e65e0 (direct-map kernel VA), printed 3/3 rounds. Passive LAN observers of the broadcast discovery exchange learn a live kernel heap address β€” KASLR-style defeat and slab reconnaissance for companion bugs (DF-3491/DF-0457 OOB walks).