DF-4110 / fix.diff
--- a/sys/dev/netif/tl/if_tl.c +++ b/sys/dev/netif/tl/if_tl.c @@ -1404,6 +1404,21 @@ m = cur_rx->tl_mbuf; total_len = cur_rx->tl_ptr->tlist_frsize; + /* + * tlist_frsize is device-written (16 bits) while the RX + * buffer is a single MCLBYTES cluster: clamp before + * trusting it as an mbuf length, otherwise a faulty or + * hostile NIC hands the stack an m_len of up to 65535 on + * a 2K cluster (OOB read propagated up the stack). + */ + if (total_len > MCLBYTES) { + IFNET_STAT_INC(ifp, ierrors, 1); + cur_rx->tl_ptr->tlist_frsize = MCLBYTES; + cur_rx->tl_ptr->tlist_cstat = TL_CSTAT_READY; + cur_rx->tl_ptr->tl_frag.tlist_dcnt = MCLBYTES; + continue; + } + if (tl_newbuf(sc, cur_rx) == ENOBUFS) { IFNET_STAT_INC(ifp, ierrors, 1); cur_rx->tl_ptr->tlist_frsize = MCLBYTES; |