DF-2419 / fix.diff
diff --git a/sys/dev/disk/ahci/ahci_cam.c b/sys/dev/disk/ahci/ahci_cam.c --- a/sys/dev/disk/ahci/ahci_cam.c +++ b/sys/dev/disk/ahci/ahci_cam.c @@ -1130,8 +1130,18 @@ /* * Use the vendor specific area to set the TRIM status * for scsi_da + * + * vendor_specific1 lives at a fixed offset (~96) inside + * scsi_inquiry_data, well past SHORT_INQUIRY_LENGTH (36). The + * length check above only requires rdata_len >= 36, so for a CCB + * with a 36..95-byte data buffer this unconditional write would + * land past the end of the kernel bounce buffer. Only emit it + * when the caller's buffer actually covers that area. + * See DF-2419. */ - if (at->at_identify.support_dsm) { + if (at->at_identify.support_dsm && + rdata_len >= offsetof(struct scsi_inquiry_data, + vendor_specific1) + 2) { rdata->inquiry_data.vendor_specific1[0] = at->at_identify.support_dsm &ATA_SUPPORT_DSM_TRIM; rdata->inquiry_data.vendor_specific1[1] = |