Message ID | 20220820015648.902562-2-john@john-millikin.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2,1/2] scsi: Add buf_len parameter to scsi_req_new() | expand |
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index b35fde0a30..abe195b22a 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -712,6 +712,8 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, SCSICommand cmd = { .len = 0 }; int ret; + assert(buf_len > 0); + if ((d->unit_attention.key == UNIT_ATTENTION || bus->unit_attention.key == UNIT_ATTENTION) && (buf[0] != INQUIRY && @@ -1316,7 +1318,7 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, cmd->lba = -1; len = scsi_cdb_length(buf); - if (len < 0) { + if (len < 0 || len > buf_len) { return -1; }
In scsi_req_parse_cdb(), if the CDB length implied by the command type exceeds the initialized portion of the command buffer, reject the request. Rejected requests are recorded by the `scsi_req_parse_bad` trace event. On example of a bug detected by this check is SunOS's use of interleaved DMA and non-DMA commands. This guest behavior currently causes QEMU to parse uninitialized memory as a SCSI command, with unpredictable outcomes. With the new check in place: * QEMU consistently creates a trace event and rejects the request. * SunOS retries the request(s) and is able to successfully boot from disk. Signed-off-by: John Millikin <john@john-millikin.com> Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1127 --- hw/scsi/scsi-bus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)