⬢ DragonFlyBSD Kernel Audit
DF-4067 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ti/if_ti.c
+++ b/sys/dev/netif/ti/if_ti.c
@@ -1632,6 +1632,7 @@
 		struct mbuf *m;
 		uint16_t vlan_tag = 0;
 		int have_tag = 0;
+		int maxlen;
 
 		cur_rx =
 		    &sc->ti_rdata->ti_rx_return_ring[sc->ti_rx_saved_considx];
@@ -1645,6 +1646,7 @@
 
 		if (cur_rx->ti_flags & TI_BDFLAG_JUMBO_RING) {
 			TI_INC(sc->ti_jumbo, TI_JUMBO_RX_RING_CNT);
+			maxlen = TI_JUMBO_FRAMELEN - ETHER_ALIGN;
 			m = sc->ti_cdata.ti_rx_jumbo_chain[rxidx];
 			sc->ti_cdata.ti_rx_jumbo_chain[rxidx] = NULL;
 			if (cur_rx->ti_flags & TI_BDFLAG_ERROR) {
@@ -1659,6 +1661,7 @@
 			}
 		} else if (cur_rx->ti_flags & TI_BDFLAG_MINI_RING) {
 			TI_INC(sc->ti_mini, TI_MINI_RX_RING_CNT);
+			maxlen = MHLEN - ETHER_ALIGN;
 			m = sc->ti_cdata.ti_rx_mini_chain[rxidx];
 			sc->ti_cdata.ti_rx_mini_chain[rxidx] = NULL;
 			if (cur_rx->ti_flags & TI_BDFLAG_ERROR) {
@@ -1673,6 +1676,7 @@
 			}
 		} else {
 			TI_INC(sc->ti_std, TI_STD_RX_RING_CNT);
+			maxlen = MCLBYTES - ETHER_ALIGN;
 			m = sc->ti_cdata.ti_rx_std_chain[rxidx];
 			sc->ti_cdata.ti_rx_std_chain[rxidx] = NULL;
 			if (cur_rx->ti_flags & TI_BDFLAG_ERROR) {
@@ -1687,6 +1691,12 @@
 			}
 		}
 
+		if (cur_rx->ti_len > maxlen) {
+			/* firmware lied about the frame length */
+			IFNET_STAT_INC(ifp, ierrors, 1);
+			m_freem(m);
+			continue;
+		}
 		m->m_pkthdr.len = m->m_len = cur_rx->ti_len;
 		IFNET_STAT_INC(ifp, ipackets, 1);
 		m->m_pkthdr.rcvif = ifp;