diff --git a/sys/dev/netif/xe/if_xe.c b/sys/dev/netif/xe/if_xe.c --- a/sys/dev/netif/xe/if_xe.c +++ b/sys/dev/netif/xe/if_xe.c @@ -749,7 +749,20 @@ struct mbuf *mbp; u_int16_t len; - len = XE_INW(XE_RBC) - ETHER_CRC_LEN; + /* + * DF-1410: XE_RBC includes 3 flag bits in the high half (XE_RBC_FULL/ + * PART/REJECT). Mask them off, then range-check the count against the + * mbuf-cluster window. RBC < ETHER_CRC_LEN would underflow the u16 + * and yield a ~64 KiB overflow into the 2 KiB cluster; oversized long + * packets (silicon accepts up to 8 KiB) overflow the same way. + */ + len = XE_INW(XE_RBC); + len &= XE_RBC_BYTE_COUNT; + if (len < ETHER_CRC_LEN || len - ETHER_CRC_LEN > MCLBYTES - 2 - 1) { + IFNET_STAT_INC(ifp, iqdrops, 1); + continue; + } + len -= ETHER_CRC_LEN; IFPRINTF(3, (ifp, "intr: receive length = %d\n", len));