⬢ DragonFlyBSD Kernel Audit
DF-4971 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mfi/mfi_cam.c
+++ b/sys/dev/raid/mfi/mfi_cam.c
@@ -143,6 +143,7 @@
 mfip_detach(device_t dev)
 {
 	struct mfip_softc *sc;
+	struct ccb_hdr *ccbh;
 
 	sc = device_get_softc(dev);
 	if (sc == NULL)
@@ -150,6 +151,18 @@
 
 	if (sc->sim != NULL) {
 		lockmgr(&sc->mfi_sc->mfi_io_lock, LK_EXCLUSIVE);
+		/*
+		 * Fail any ccbs still parked in the SIM-private queue so
+		 * CAM can reclaim them, and drop the callback so the still
+		 * live mfi core can never dispatch through a freed mfip.
+		 */
+		while ((ccbh = TAILQ_FIRST(&sc->mfi_sc->mfi_cam_ccbq)) != NULL) {
+			TAILQ_REMOVE(&sc->mfi_sc->mfi_cam_ccbq, ccbh,
+			    sim_links.tqe);
+			ccbh->status = CAM_REQ_ABORTED;
+			xpt_done((union ccb *)ccbh);
+		}
+		sc->mfi_sc->mfi_cam_start = NULL;
 		xpt_bus_deregister(cam_sim_path(sc->sim));
 		cam_sim_free(sc->sim);
 		lockmgr(&sc->mfi_sc->mfi_io_lock, LK_RELEASE);