diff --git a/sys/dev/netif/bwn/bwn/if_bwn.c b/sys/dev/netif/bwn/bwn/if_bwn.c --- a/sys/dev/netif/bwn/bwn/if_bwn.c +++ b/sys/dev/netif/bwn/bwn/if_bwn.c @@ -5483,7 +5483,14 @@ BUS_DMASYNC_PREWRITE); return; } - if (len > dr->dr_rx_bufsize) { + /* The RX mbuf cluster is MCLBYTES (2048) but dr_rx_bufsize is + * IEEE80211_MAX_LEN (2312); a device-reported frame_len in + * (MCLBYTES - dr_frameoffset, dr_rx_bufsize] passes the existing + * check yet makes m_len = len + dr_frameoffset exceed the cluster, + * causing a heap OOB read when the frame is processed. Drop frames + * that cannot fit in the actual cluster. */ + if (len > dr->dr_rx_bufsize || + (u_int)len + dr->dr_frameoffset > MCLBYTES) { tmp = len; while (1) { dr->getdesc(dr, *slot, &desc, &meta);