⬢ DragonFlyBSD Kernel Audit
DF-4234 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/txp/if_txp.c
+++ b/sys/dev/netif/txp/if_txp.c
@@ -317,6 +317,7 @@
 			       ifp->if_serializer);
 	if (error) {
 		device_printf(dev, "couldn't set up irq\n");
+		ifmedia_removeall(&sc->sc_ifmedia);
 		ether_ifdetach(ifp);
 		goto fail;
 	}
@@ -333,7 +334,6 @@
 {
 	struct txp_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
-	int i;
 
 	lwkt_serialize_enter(ifp->if_serializer);
 
@@ -346,9 +346,6 @@
 	ifmedia_removeall(&sc->sc_ifmedia);
 	ether_ifdetach(ifp);
 
-	for (i = 0; i < RXBUF_ENTRIES; i++)
-		kfree(sc->sc_rxbufs[i].rb_sd, M_DEVBUF);
-
 	txp_release_resources(dev);
 
 	return(0);
@@ -358,6 +355,7 @@
 txp_release_resources(device_t dev)
 {
 	struct txp_softc *sc;
+	int i;
 
 	sc = device_get_softc(dev);
 
@@ -367,6 +365,13 @@
 	if (sc->sc_res != NULL)
 		bus_release_resource(dev, TXP_RES, TXP_RID, sc->sc_res);
 
+	/* Free per-slot swdescs before the ldata block that names them */
+	if (sc->sc_rxbufs != NULL) {
+		for (i = 0; i < RXBUF_ENTRIES; i++)
+			kfree(sc->sc_rxbufs[i].rb_sd, M_DEVBUF);
+		sc->sc_rxbufs = NULL;
+	}
+
 	if (sc->sc_ldata != NULL)
 		contigfree(sc->sc_ldata, sizeof(struct txp_ldata), M_DEVBUF);