⬢ DragonFlyBSD Kernel Audit
DF-3898 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mps/mps_sas.c b/sys/dev/raid/mps/mps_sas.c
index 1111111..2222222 100644
--- a/sys/dev/raid/mps/mps_sas.c
+++ b/sys/dev/raid/mps/mps_sas.c
@@ -826,9 +826,21 @@ mps_detach_sas(struct mps_softc *sc)
 		if (sassc->flags & MPSSAS_SCANTHREAD) {
 			lksleep(&sassc->flags, &sc->mps_lock, 0,
 			       "mps_shutdown", 30 * hz);
 		}
 	}
 	mps_unlock(sc);
 
+	if (sassc->flags & MPSSAS_SCANTHREAD) {
+		/*
+		 * DF-3898: the scanner thread is still inside xpt_action on
+		 * this sim (scan legs over wedged targets can exceed the
+		 * 30-second bound).  Freeing sassc/sim now is a use-after-
+		 * free; leak the structures instead.
+		 */
+		device_printf(sc->mps_dev, "mps_scan thread did not stop; "
+		    "leaking mpssas_softc to avoid use-after-free\n");
+		sc->sassc = NULL;
+		return (0);
+	}
+
 	kfree(sassc->targets, M_MPT2);
 	kfree(sassc, M_MPT2);
 	sc->sassc = NULL;