⬢ DragonFlyBSD Kernel Audit
DF-5285 / fix.diff
← back to finding ↓ download raw
--- sys/bus/cam/scsi/scsi_sa.c.orig
+++ sys/bus/cam/scsi/scsi_sa.c
@@ -752,7 +752,7 @@
 		 */
 		if (((softc->blk_mask != ~0) &&
 		    ((bp->b_bcount & softc->blk_mask) != 0)) ||
-		    ((softc->blk_mask == ~0) &&
+		    ((softc->blk_mask == ~0) && softc->min_blk > 0 &&
 		    ((bp->b_bcount % softc->min_blk) != 0))) {
 			xpt_print(periph->path, "Invalid request.  Fixed block "
 			    "device requests must be a multiple of %d bytes\n",
@@ -1958,7 +1958,7 @@
 		 * blocksize on tape is and don't expect to really
 		 * read a full record.
 		 */
-		rblim = kmalloc(8192, M_SCSISA, M_INTWAIT);
+		rblim = kmalloc(8192, M_SCSISA, M_INTWAIT | M_ZERO);
 
 		if ((softc->quirks & SA_QUIRK_NODREAD) == 0) {
 			scsi_sa_read_write(&ccb->csio, 0, sadone,
@@ -2021,6 +2021,14 @@
 
 		}
 		/*
+		 * DF-5285: a device that reports minimum == 0 (or a failed
+		 * READ BLOCK LIMITS) must not leave min_blk == 0 around:
+		 * sastrategy()'s fixed-block validation divides by it.
+		 */
+		if (softc->min_blk == 0) {
+			softc->min_blk = 1;
+		}
+		/*
 		 * Next, perform a mode sense to determine
 		 * current density, blocksize, compression etc.
 		 */
@@ -2754,7 +2762,7 @@
 
 	softc = (struct sa_softc *)periph->softc;
 
-	ccomp = kmalloc(sizeof (sa_comp_t), M_SCSISA, M_INTWAIT);
+	ccomp = kmalloc(sizeof (sa_comp_t), M_SCSISA, M_INTWAIT | M_ZERO);
 
 	/*
 	 * Since it doesn't make sense to set the number of blocks, or