--- a/sys/dev/netif/bce/if_bce.c +++ b/sys/dev/netif/bce/if_bce.c @@ -4393,11 +4393,24 @@ bce_rx_intr(struct bce_rx_ring *rxr, int count, uint16_t hw_cons) l2fhdr = mtod(m, struct l2_fhdr *); len = l2fhdr->l2_fhdr_pkt_len; status = l2fhdr->l2_fhdr_status; + /* + * Sanity check the NIC-reported frame length before + * using it: pkt_len covers l2_fhdr + pad + frame + FCS + * and must fit in the posted MCLBYTES cluster. Out of + * range values (faulty/malicious device or firmware + * erratum) would otherwise set m_len past the cluster + * (heap OOB read) or underflow the unsigned length + * below (m_len ~ 4GB, guaranteed panic). + */ + if (len < sizeof(struct l2_fhdr) + ETHER_ALIGN + + ETHER_CRC_LEN || len > MCLBYTES) { + IFNET_STAT_INC(ifp, ierrors, 1); + + /* Reuse the mbuf for a new frame. */ + bce_setup_rxdesc_std(rxr, sw_chain_prod, + &sw_prod_bseq); + m = NULL; + goto bce_rx_int_next_rx; + } len -= ETHER_CRC_LEN; /* Check the received frame for errors. */ if (status & (L2_FHDR_ERRORS_BAD_CRC | L2_FHDR_ERRORS_PHY_DECODE |