diff --git a/sys/bus/cam/scsi/scsi_ch.c b/sys/bus/cam/scsi/scsi_ch.c --- a/sys/bus/cam/scsi/scsi_ch.c +++ b/sys/bus/cam/scsi/scsi_ch.c @@ -1161,6 +1161,15 @@ if (avail != cesr->cesr_element_count) { xpt_print(periph->path, "warning, READ ELEMENT STATUS avail != count\n"); + /* + * The data buffer was sized for exactly cesr_element_count + * descriptors (above). A malicious target can report an avail + * larger than that, which would stride the parse loop past the + * allocation and leak adjacent kernel heap to userspace. Clamp + * to the requested count. + */ + if (avail > cesr->cesr_element_count) + avail = cesr->cesr_element_count; } user_data = (struct changer_element_status *)