⬢ DragonFlyBSD Kernel Audit
DF-4110 / fix.diff
← back to finding ↓ download raw
--- 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;