DF-0994 / fix.diff
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) { |