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)