⬢ DragonFlyBSD Kernel Audit
DF-5043 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/advansys/adv_pci.c
+++ b/sys/dev/disk/advansys/adv_pci.c
@@ -258,6 +258,12 @@
 	}
 
 	if (adv_init(adv) != 0) {
+		/*
+		 * adv_free() at init_level 1 (the ccb_infos teardown tier)
+		 * does not destroy parent_dmat; unwind it explicitly, like
+		 * the overrun-allocation failure paths above already do.
+		 */
+		bus_dma_tag_destroy(adv->parent_dmat);
 		adv_free(adv);
 		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
 		return ENXIO;
@@ -288,6 +294,16 @@
 				    RF_SHAREABLE | RF_ACTIVE);
 	if (irqres == NULL ||
 	    bus_setup_intr(dev, irqres, 0, adv_intr, adv, &ih, NULL)) {
+		/*
+		 * Mirror the overrun-path unwinds: parent_dmat is not
+		 * covered by adv_free() at init_level 1, and the active
+		 * IRQ resource must be released when bus_setup_intr()
+		 * failed after bus_alloc_resource() succeeded.
+		 */
+		bus_dma_tag_destroy(adv->parent_dmat);
+		if (irqres != NULL)
+			bus_release_resource(dev, SYS_RES_IRQ, irqrid,
+					     irqres);
 		adv_free(adv);
 		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
 		return ENXIO;