⬢ DragonFlyBSD Kernel Audit
DF-5153 / fix.diff
← back to finding ↓ download raw
diff -ruN a/sys/dev/raid/dpt/dpt.h b/sys/dev/raid/dpt/dpt.h
--- a/sys/dev/raid/dpt/dpt.h	2026-09-30 12:02:11.249193278 +0000
+++ b/sys/dev/raid/dpt/dpt.h	2026-09-30 12:02:21.201065193 +0000
@@ -45,6 +45,7 @@
 #define _DPT_H
 
 #include <sys/ioccom.h>
+#include <sys/eventhandler.h>
 
 #undef DPT_USE_DLM_SWI
 
@@ -989,6 +990,7 @@
 	bus_dma_tag_t		  sg_dmat;	/* dmat for our sg maps */
 	SLIST_HEAD(, sg_map_node) sg_maps;
 
+	eventhandler_tag	  shut_tag;	/* shutdown_post_sync tag */
 	struct cam_sim		  *sims[MAX_CHANNELS];
 	struct cam_path		  *paths[MAX_CHANNELS];
 	u_int32_t commands_processed;
diff -ruN a/sys/dev/raid/dpt/dpt_pci.c b/sys/dev/raid/dpt/dpt_pci.c
--- a/sys/dev/raid/dpt/dpt_pci.c	2026-09-30 12:02:11.253193227 +0000
+++ b/sys/dev/raid/dpt/dpt_pci.c	2026-09-30 12:02:21.209065090 +0000
@@ -37,6 +37,9 @@
 #include <sys/rman.h>
 #include <sys/thread2.h>
 
+#include <bus/cam/cam.h>
+#include <bus/cam/cam_sim.h>
+#include <bus/cam/cam_xpt_sim.h>
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
@@ -70,6 +73,7 @@
 dpt_pci_attach (device_t dev)
 {
 	dpt_softc_t *	dpt;
+	int		io_rid = 0;
 	struct resource *io = NULL;
 	struct resource *irq = NULL;
 	int		rid;
@@ -84,12 +88,14 @@
 #ifdef DPT_ALLOW_MMIO
 	if ((command & PCIM_CMD_MEMEN) != 0) {
 		rid = DPT_PCI_MEMADDR;
+		io_rid = rid;
 		iotype = SYS_RES_MEMORY;
 		io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE);
 	}
 #endif
 	if (io == NULL && (command &  PCIM_CMD_PORTEN) != 0) {
 		rid = DPT_PCI_IOADDR;
+		io_rid = rid;
 		iotype = SYS_RES_IOPORT;
 		io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE);
 	}
@@ -165,6 +171,29 @@
 	if (error) {
 		device_printf(dev, "Unable to register interrupt handler\n");
 		error = ENXIO;
+		/*
+		 * dpt_attach() has already registered our sims/paths
+		 * with CAM and our shutdown handler; unwind all of it or
+		 * the SIM stays live against released resources (DF-5153).
+		 */
+		crit_enter();
+		for (int ch = 0; ch < MAX_CHANNELS; ch++) {
+			if (dpt->paths[ch] != NULL) {
+				xpt_free_path(dpt->paths[ch]);
+				dpt->paths[ch] = NULL;
+			}
+			if (dpt->sims[ch] != NULL) {
+				xpt_bus_deregister(
+					cam_sim_path(dpt->sims[ch]));
+				cam_sim_free(dpt->sims[ch]);
+				dpt->sims[ch] = NULL;
+			}
+		}
+		EVENTHANDLER_DEREGISTER(shutdown_post_sync, dpt->shut_tag);
+		dpt_free(dpt);
+		crit_exit();
+		/* parent_dmat is created by this glue, not by dpt_init() */
+		bus_dma_tag_destroy(dpt->parent_dmat);
 		goto bad;
 	}
 
@@ -172,7 +201,7 @@
 
 bad:
 	if (io)
-		bus_release_resource(dev, iotype, 0, io);
+		bus_release_resource(dev, iotype, io_rid, io);
 	if (irq)
 		bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
 
diff -ruN a/sys/dev/raid/dpt/dpt_scsi.c b/sys/dev/raid/dpt/dpt_scsi.c
--- a/sys/dev/raid/dpt/dpt_scsi.c	2026-09-30 12:02:11.249193278 +0000
+++ b/sys/dev/raid/dpt/dpt_scsi.c	2026-09-30 12:02:21.209065090 +0000
@@ -1484,8 +1484,9 @@
 	}
 	cam_simq_release(devq);
 	if (i > 0)
-		EVENTHANDLER_REGISTER(shutdown_post_sync, dptshutdown,
-				      dpt, SHUTDOWN_PRI_DRIVER);
+		dpt->shut_tag = EVENTHANDLER_REGISTER(shutdown_post_sync,
+						      dptshutdown, dpt,
+						      SHUTDOWN_PRI_DRIVER);
 	return (i);
 }