diff --git a/sys/dev/raid/hptmv/entry.c b/sys/dev/raid/hptmv/entry.c --- a/sys/dev/raid/hptmv/entry.c +++ b/sys/dev/raid/hptmv/entry.c @@ -2707,6 +2707,17 @@ break; case INQUIRY: + /* + * cam_periph_mapmem() sizes the kernel bounce + * buffer at exactly dxfer_len bytes. Reject any + * undersized INQUIRY before we write the full + * sizeof(INQUIRYDATA) reply into it; otherwise + * SetInquiryData() overflows the allocation. + */ + if (csio->dxfer_len < sizeof(INQUIRYDATA)) { + ccb_h->status = CAM_REQ_INVALID; + break; + } ZeroMemory(ccb->csio.data_ptr, ccb->csio.dxfer_len); SetInquiryData((PINQUIRYDATA)ccb->csio.data_ptr, pVDev); ccb_h->status = CAM_REQ_CMP; @@ -2717,6 +2728,11 @@ UCHAR *rbuf=csio->data_ptr; unsigned int cap; + /* READ_CAPACITY reply is 8 bytes (rbuf[0..7]). */ + if (csio->dxfer_len < 8) { + ccb_h->status = CAM_REQ_INVALID; + break; + } if (pVDev->VDeviceCapacity > 0xfffffffful) { cap = 0xfffffffful; } else { @@ -2742,6 +2758,11 @@ UCHAR *rbuf = csio->data_ptr; LBA_T cap = pVDev->VDeviceCapacity - 1; + /* SERVICE_ACTION_IN reply is 12 bytes (rbuf[0..11]). */ + if (csio->dxfer_len < 12) { + ccb_h->status = CAM_REQ_INVALID; + break; + } rbuf[0] = (UCHAR)(cap>>56); rbuf[1] = (UCHAR)(cap>>48); rbuf[2] = (UCHAR)(cap>>40);