aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi/scsi-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/scsi/scsi-bus.c')
-rw-r--r--hw/scsi/scsi-bus.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index b2e2bc3c96..cc71524024 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -102,15 +102,15 @@ static void scsi_device_unrealize(SCSIDevice *s)
}
int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
- void *hba_private)
+ size_t buf_len, void *hba_private)
{
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
int rc;
assert(cmd->len == 0);
- rc = scsi_req_parse_cdb(dev, cmd, buf);
+ rc = scsi_req_parse_cdb(dev, cmd, buf, buf_len);
if (bus->info->parse_cdb) {
- rc = bus->info->parse_cdb(dev, cmd, buf, hba_private);
+ rc = bus->info->parse_cdb(dev, cmd, buf, buf_len, hba_private);
}
return rc;
}
@@ -703,7 +703,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
}
SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
- uint8_t *buf, void *hba_private)
+ uint8_t *buf, size_t buf_len, void *hba_private)
{
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
const SCSIReqOps *ops;
@@ -734,9 +734,9 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
}
if (ops != NULL || !sc->parse_cdb) {
- ret = scsi_req_parse_cdb(d, &cmd, buf);
+ ret = scsi_req_parse_cdb(d, &cmd, buf, buf_len);
} else {
- ret = sc->parse_cdb(d, &cmd, buf, hba_private);
+ ret = sc->parse_cdb(d, &cmd, buf, buf_len, hba_private);
}
if (ret != 0) {
@@ -1308,7 +1308,8 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
}
}
-int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
+int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
+ size_t buf_len)
{
int rc;
int len;
@@ -1713,7 +1714,11 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size,
qemu_get_buffer(f, buf, sizeof(buf));
qemu_get_be32s(f, &tag);
qemu_get_be32s(f, &lun);
- req = scsi_req_new(s, tag, lun, buf, NULL);
+ /*
+ * A too-short CDB would have been rejected by scsi_req_new, so just use
+ * SCSI_CMD_BUF_SIZE as the CDB length.
+ */
+ req = scsi_req_new(s, tag, lun, buf, sizeof(buf), NULL);
req->retry = (sbyte == 1);
if (bus->info->load_request) {
req->hba_private = bus->info->load_request(f, req);