⬢ DragonFlyBSD Kernel Audit
DF-5327 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/cam/scsi/scsi_ch.c
+++ b/sys/bus/cam/scsi/scsi_ch.c
@@ -412,17 +412,24 @@
 		return(ENXIO);
 	}
 
-	if ((softc->flags & CH_FLAG_OPEN) == 0)
-		softc->flags |= CH_FLAG_OPEN;
-	else
-		cam_periph_release(periph);
-
+	/*
+	 * DF-5327 fix: take the hold BEFORE publishing CH_FLAG_OPEN /
+	 * dropping a secondary opener's acquire.  cam_periph_hold() already
+	 * releases its own reference when it is signal-interrupted, so on
+	 * failure we only undo our acquire -- the flag/refcount state can
+	 * no longer disagree.
+	 */
 	if ((error = cam_periph_hold(periph, PCATCH)) != 0) {
 		cam_periph_unlock(periph);
 		cam_periph_release(periph);
 		return (error);
 	}
 
+	if ((softc->flags & CH_FLAG_OPEN) == 0)
+		softc->flags |= CH_FLAG_OPEN;
+	else
+		cam_periph_release(periph);
+
 	/*
 	 * Load information about this changer device into the softc.
 	 */