⬢ DragonFlyBSD Kernel Audit
DF-3639 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/bnx/if_bnx.c
+++ b/sys/dev/netif/bnx/if_bnx.c
@@ -2844,6 +2844,25 @@
 			continue;
 		}
 
+		/*
+		 * Sanity check the NIC-reported frame length before
+		 * using it: bge_len covers the frame plus the trailing
+		 * EtherCRC and must fit in the posted buffer
+		 * (m_len == MCLBYTES - ETHER_ALIGN == 2046 for the std
+		 * ring).  A faulty or malicious device writing an
+		 * out-of-range bge_len into the return-ring BD would
+		 * otherwise make the mbuf describe up to 65531 bytes
+		 * inside the 2048-byte cluster (kernel heap OOB read /
+		 * info leak via bpf and the network stack).
+		 */
+		if (__predict_false(cur_rx->bge_len <
+		    ETHER_HDR_LEN + ETHER_CRC_LEN) ||
+		    __predict_false(cur_rx->bge_len - ETHER_CRC_LEN >
+		    m->m_len)) {
+			IFNET_STAT_INC(ifp, ierrors, 1);
+			m_freem(m);
+			continue;
+		}
 		IFNET_STAT_INC(ifp, ipackets, 1);
 		m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
 		m->m_pkthdr.rcvif = ifp;