DF-4045 / fix.diff
--- 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. */ |