--- a/sys/dev/disk/nata/atapi-cd.c +++ b/sys/dev/disk/nata/atapi-cd.c @@ -1141,6 +1141,13 @@ (caddr_t)¶m, 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); }