--- a/sys/dev/netif/igb/if_igb.c +++ b/sys/dev/netif/igb/if_igb.c @@ -2181,6 +2181,13 @@ first = txr->next_to_clean; if (first == hdr) return; + /* + * The TX head comes from the NIC TX-head write-back buffer and + * must never be trusted; an out-of-range value would spin this + * loop forever (or trip the KKASSERT below on INVARIANTS builds). + */ + if (hdr < 0 || hdr >= txr->num_tx_desc) + return; avail = txr->tx_avail; while (first != hdr) { @@ -2229,6 +2236,9 @@ hdr = E1000_READ_REG(&txr->sc->hw, E1000_TDH(txr->me)), first = txr->next_to_clean; + /* Never trust the hardware head index (see igb_txeof()). */ + if (hdr < 0 || hdr >= txr->num_tx_desc) + goto done; if (first == hdr) goto done; txr->tx_gc++;