DragonFlyBSD Kernel Audit
DF-0994 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/bus/cam/scsi/scsi_sa.c b/sys/bus/cam/scsi/scsi_sa.c
--- a/sys/bus/cam/scsi/scsi_sa.c
+++ b/sys/bus/cam/scsi/scsi_sa.c
@@ -1622,6 +1622,12 @@
 				bp->b_error = 0;
 				if (bioq_first(&softc->bio_queue) != NULL) {
 					biodone(done_bio);
+					/* DF-0994: refresh bio before looping, otherwise the
+						* again: label re-uses the just-biodone'd bio,
+						* underflowing queue_count, double-removing it from
+						* the TAILQ, and calling biodone() on it a second
+						* time (double biodone / buf UAF). */
+					bio = bioq_first(&softc->bio_queue);
 					goto again;
 				}
 			} else if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {