⬢ DragonFlyBSD Kernel Audit
DF-4184 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/nata/atapi-cd.c
+++ b/sys/dev/disk/nata/atapi-cd.c
@@ -1141,6 +1141,13 @@
 				(caddr_t)&param, sizeof(param))))
 	return error;
 
+    /* page_length is device-supplied and sizes a MODE SELECT data-out
+     * transfer out of this sizeof(param)-byte stack buffer; clamp it to the
+     * MMC write-parameters-page maximum so no stack bytes beyond the
+     * struct can be sent to the device. */
+    if (param.page_length < 1 || param.page_length > 0x32)
+	return EINVAL;
+
     param.data_length = 0;
     if (multisession)
 	param.session_type = CDR_SESS_MULTI;
@@ -1156,7 +1163,13 @@
 
     /* some drives just return ready, wait for the expected fixate time */
     if ((error = acd_test_ready(dev)) != EBUSY) {
-	timeout = timeout / (cdp->cap.cur_write_speed / 177);
+	int write_speed = cdp->cap.cur_write_speed;
+
+	/* acd_get_cap() may have failed at attach (all 5 attempts), leaving
+	 * cur_write_speed == 0; clamp the divisor. */
+	if (write_speed < 177)
+	    write_speed = 177;
+	timeout = timeout / (write_speed / 177);
 	tsleep(&error, 0, "acdfix", timeout * hz / 2);
 	return acd_test_ready(dev);
     }