DragonFlyBSD Kernel Audit
DF-1410 / fix.diff
← back to finding ↓ download raw
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));