DF-3966 / trigger.c
/* * DF-3966 trigger sketch — rt2661_rx_intr trusts device-fed frame length * ===================================================================== * rt2661.c:1101-1102: * * m->m_pkthdr.len = m->m_len = * (le32toh(desc->flags) >> 16) & 0xfff; // up to 4095 * * desc->flags is written by the NIC via DMA (rx descriptor ring, allocated in * rt2661_alloc_rx_ring). The mbuf is a 2 KB cluster: * rt2661.c:1055 mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); * MCLBYTES = 1<<MCLSHIFT = 1<<11 = 2048 (sys/sys/param.h:494-497) * * No clamp: a descriptor claiming any length in (2048, 4095] makes * ieee80211_input(ni, m, rssi, nf) (rt2661.c:1132-1138) parse up to 2047 * bytes past the end of the 2 KB cluster as if they were frame content. * The 802.11 payload (after decryption/defrag) is handed to the network * stack and can reach userland (e.g. as UDP payload in monitor/managed * modes), disclosing adjacent kernel heap memory; short of that, parser OOB * reads can drive panics (malformed len/type fields read OOB). * * Threat model: malicious/compromised NIC firmware, or a PCIe/Thunderbolt * DMA attack on the descriptor — the same device-trust class as the rest of * this driver family (cf. rt2860 DF-3748..3753). A *buggy* (not malicious) * NIC setting the length word over 2048 would hit this too, since the field * is 12 bits wide by spec while the buffer is 11 bits. * * Trigger on hardware (RT2561/RT2561S/RT2661, if_ral.ko): * 1. bring the interface up in monitor mode: ifconfig wlan0 create wlandev * ral0 wlanmode monitor; ifconfig wlan0 up * 2. from a controlled/emulated device (or patched firmware) post one RX * descriptor with flags[27:16] = 0xfff and only a short frame in the * cluster; * 3. capture on wlan0 (tcpdump -i wlan0 -w out.pcap): trailing bytes of * the delivered frame contain kernel heap memory from beyond the * cluster. */ int main(void) { return 0; } |