DF-3840 / trigger.c
/* * DF-3840 PoC trigger (documentation harness โ hardware-gated path). * * Use-after-free READ in iwi_frame_intr() (if_iwi.c): * iwi_rx_intr() calls iwi_frame_intr(sc, data, idx, (struct iwi_frame * *)(hdr + 1)) โ `frame` points INTO the current rx mbuf cluster. * iwi_frame_intr() swaps data->m to a fresh mbuf (if_iwi.c:1314-1315), * drops IWI_LOCK, and hands the OLD mbuf `m` to ieee80211_input() * (if_iwi.c:1337-1342). net80211 consumes the mbuf โ drop paths free it * synchronously (sys/netproto/802_11/wlan/ieee80211_input.c:169/211/245). * After re-taking the lock, the driver reads `frame->rate` from the freed * cluster: * if_iwi.c:1345 if (sc->sc_softled) { <- default ON * if_iwi.c:1352 if (type == IEEE80211_FC0_TYPE_DATA) * if_iwi.c:1353 sc->sc_rxrate = frame->rate; <-- UAF read * * Trigger: on a machine with an Intel 2200BG/2915ABG (if_iwi) associated in * BSS mode with hw.iwiN.softled=1 (default), receive any 802.11 DATA frame * that ieee80211_input() drops synchronously (e.g. a frame for another * station in monitor mode, or a bad-FCS frame accepted in monitor mode). * Each such frame performs a 1-byte read of a freed mbuf cluster. * * Nothing to execute in userspace on a guest without the NIC; this file * documents the exact path. See VERDICT.md for the line-by-line trace. */ int main(void) { /* * A real trigger is: associate an iwi(4) station and capture one * data frame (any tcpdump -i iwi0 traffic while associated). With * ddb compiled in, a prior `w watch+...(kmalloc free of the cluster)` * breakpoint on m_freem's cluster free shows the read at * if_iwi.c:1353 occurring after the free. */ return 0; } |