⬢ DragonFlyBSD Kernel Audit
DF-3931 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mly/mly.c
+++ b/sys/dev/raid/mly/mly.c
@@ -527,8 +527,19 @@ mly_shutdown(device_t dev)
     if (sc->mly_state & MLY_STATE_OPEN)
 	return(EBUSY);
 
-    /* kill the periodic event */
-    callout_stop(&sc->mly_periodic);
+    /*
+     * Kill the periodic event.  callout_terminate() (unlike
+     * callout_stop()) also prevents a callback that is currently
+     * executing (and would re-arm itself at its tail,
+     * mly.c:1397) from leaving the callout pending again after
+     * we return; a surviving re-arm would fire on the freed
+     * softc once mly_free() runs.
+     */
+    callout_terminate(&sc->mly_periodic);
+
+    /* refuse to detach with commands still in flight */
+    if (!TAILQ_EMPTY(&sc->mly_busy) || !TAILQ_EMPTY(&sc->mly_complete))
+	return(EBUSY);
 
     /* flush controller */
     mly_printf(sc, "flushing cache...");