⬢ DragonFlyBSD Kernel Audit
DF-3668 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ix/if_ix.c
+++ b/sys/dev/netif/ix/if_ix.c
@@ -2360,6 +2374,16 @@
 	if (txr->tx_avail == txr->tx_ndesc)
 		return;
 
+	/*
+	 * hdr is the NIC-DMA'd TX head write-back (*(txr->tx_hdr)) or the
+	 * TDH register.  A hostile or hung NIC reporting an index outside
+	 * [0, tx_ndesc) would send the cleanup loop below into an
+	 * unbounded spin (interrupt-context soft-lockup / INVARIANTS
+	 * KKASSERT panic / tx_avail overflow); treat it as spurious.
+	 */
+	if (hdr < 0 || hdr >= txr->tx_ndesc)
+		return;
+
 	first = txr->tx_next_clean;
 	if (first == hdr)
 		return;
@@ -2398,6 +2422,8 @@
 		return;
 
 	hdr = IXGBE_READ_REG(&txr->tx_sc->hw, IXGBE_TDH(txr->tx_idx));
+	if (hdr < 0 || hdr >= txr->tx_ndesc)
+		return;
 	first = txr->tx_next_clean;
 	if (first == hdr)
 		goto done;