virtio_scsi_load_request() uses assert() and exit(1) for conditions that can be triggered by a crafted migration stream: an out-of-range queue index, a malformed SCSI request, or a command mode mismatch.
Replace these with proper error returns so the migration fails gracefully instead of aborting the destination QEMU process. Cc: [email protected] Fixes: 5db1764cc1f6 ("virtio-scsi: add migration support") Fixes: d2ad7dd46e72 ("virtio-scsi: add multiqueue capability") Fixes: 36b15c79aa1b ("virtio-scsi: start preparing for any_layout") Signed-off-by: Laurent Vivier <[email protected]> --- hw/scsi/virtio-scsi.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 8dd0b88a30c4..b34cda8fd85a 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -271,7 +271,10 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq) uint32_t n; qemu_get_be32s(f, &n); - assert(n < vs->conf.num_queues); + if (n >= vs->conf.num_queues) { + return NULL; + } + req = qemu_get_virtqueue_element(vdev, f, sizeof(VirtIOSCSIReq) + vs->cdb_size); if (!req) { @@ -283,14 +286,19 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq) if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size, sizeof(VirtIOSCSICmdResp) + vs->sense_size) < 0) { error_report("invalid SCSI request migration data"); - exit(1); + virtio_scsi_free_req(req); + return NULL; } scsi_req_ref(sreq); req->sreq = sreq; - if (req->sreq->cmd.mode != SCSI_XFER_NONE) { - assert(req->sreq->cmd.mode == req->mode); + if (req->sreq->cmd.mode != SCSI_XFER_NONE && + req->sreq->cmd.mode != req->mode) { + scsi_req_unref(sreq); + virtio_scsi_free_req(req); + return NULL; } + return req; } -- 2.54.0
