⬢ DragonFlyBSD Kernel Audit
DF-4045 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/stge/if_stge.c
+++ b/sys/dev/netif/stge/if_stge.c
@@ -1605,6 +1605,27 @@
 		if ((status & RFD_FrameEnd) != 0)
 			mp->m_len = RFD_RxDMAFrameLen(status) -
 			    sc->sc_cdata.stge_rxlen;
+
+		/*
+		 * Bound the device-fed frame length against the actual
+		 * per-buffer capacity before trusting it: DMAFrameLen is
+		 * a raw 16-bit NIC-DMA'd field (RFD_RxDMAFrameLen,
+		 * if_stgereg.h:167) and the only existing check
+		 * (pkthdr.len > sc_if_framesize, below) still allows a
+		 * FrameEnd descriptor to claim more bytes than the
+		 * MCLBYTES cluster holds (jumbo MTU) or fewer than
+		 * already accumulated (negative m_len).
+		 */
+		if ((status & RFD_FrameEnd) != 0 &&
+		    (mp->m_len < 0 || mp->m_len > MCLBYTES)) {
+			/* Device lied about the frame length; drop it. */
+			IFNET_STAT_INC(ifp, ierrors, 1);
+			m_freem(mp);
+			if (sc->sc_cdata.stge_rxhead != NULL)
+				m_freem(sc->sc_cdata.stge_rxhead);
+			STGE_RXCHAIN_RESET(sc);
+			continue;
+		}
 		sc->sc_cdata.stge_rxlen += mp->m_len;
 
 		/* Chain mbufs. */