⬢ DragonFlyBSD Kernel Audit
DF-3669 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ix/if_ix.c
+++ b/sys/dev/netif/ix/if_ix.c
@@ -695,6 +695,20 @@
 	}
 	callout_terminate(&sc->fw_timer);
 
+	/*
+	 * ix_txgc_timer() re-arms itself every tick (if_ix.c:373); a mere
+	 * callout_stop() in ix_stop() cannot prevent an in-flight callback
+	 * from re-arming after we stop it, and the re-armed callout would
+	 * fire on tx_rings after ix_free_rings() below (use-after-free).
+	 * callout_terminate() disarms AND waits for any running callback.
+	 */
+	if (sc->tx_rings != NULL) {
+		int t;
+
+		for (t = 0; t < sc->tx_ring_cnt; ++t)
+			callout_terminate(&sc->tx_rings[t].tx_gc_timer);
+	}
+
 	if (sc->mem_res != NULL) {
 		uint32_t ctrl_ext;