DragonFlyBSD Kernel Audit
DF-0987 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/bus/cam/scsi/scsi_cd.c b/sys/bus/cam/scsi/scsi_cd.c
--- a/sys/bus/cam/scsi/scsi_cd.c
+++ b/sys/bus/cam/scsi/scsi_cd.c
@@ -2949,6 +2949,19 @@
 	if (num_entries <= 0)
 		goto bailout;
 
+	/* DF-0987: num_entries is derived from the device-reported
+	 * starting/ending_track with no upper bound.  softc->toc.entries is a
+	 * fixed array of 100 entries and cdreadtoc() DMAs toclen+4 bytes into
+	 * the 804-byte softc->toc.  A malicious CD claiming ending_track=255,
+	 * starting_track=0 yields 257 entries -> 1256-byte heap overflow.
+	 * Cap to the array size, matching the clamp already done on the
+	 * CDIOREADTOCENTRYS ioctl path. */
+	if (num_entries > nitems(softc->toc.entries)) {
+		xpt_print(periph->path, "bogus TOC: %d entries, clamping to %zu\n",
+		    num_entries, nitems(softc->toc.entries));
+		num_entries = nitems(softc->toc.entries);
+	}
+
 	toclen = num_entries * sizeof(struct cd_toc_entry);
 
 	error = cdreadtoc(periph, CD_MSF_FORMAT, toch->starting_track,