DragonFlyBSD Kernel Audit
DF-2490 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/nata/ata-lowlevel.c b/sys/dev/disk/nata/ata-lowlevel.c
--- a/sys/dev/disk/nata/ata-lowlevel.c
+++ b/sys/dev/disk/nata/ata-lowlevel.c
@@ -327,6 +327,13 @@
     /* ATAPI PIO commands */
     case ATA_R_ATAPI:
 	length = ATA_IDX_INB(ch, ATA_CYL_LSB)|(ATA_IDX_INB(ch, ATA_CYL_MSB)<<8);
+	/* Per-DRQ byte count is device-controlled (max 65535); cap it at the
+	 * remaining request buffer so a malicious/buggy ATAPI device cannot
+	 * drive donecount past bytecount (which would wrap transfersize via
+	 * the unsigned subtraction in the ATAPI_P_READ/WRITE cases and cause
+	 * heap OOB write/read).  See DF-2490. */
+	if (length > (request->bytecount - request->donecount))
+	    length = request->bytecount - request->donecount;
 
 	/* on timeouts we have no data or anything so just return */
 	if (request->flags & ATA_R_TIMEOUT)