virtio-scsi: fix use-after-free of VirtIOSCSIReq
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 7 Oct 2014 23:19:00 +0000 (01:19 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 9 Oct 2014 13:36:15 +0000 (15:36 +0200)
scsi_req_continue can complete the request and cause the VirtIOSCSIReq
to be freed.  Fetch req->sreq just once to avoid the bug.

Reported-by: Richard Jones <rjones@redhat.com>
Tested-by: Richard Jones <rjones@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
hw/scsi/virtio-scsi.c

index 203e62449aa100825f02dc95981933307fb4c1c8..6c02fe2b9a53a72fa1a343f5993332152c21ba03 100644 (file)
@@ -545,11 +545,12 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
 
 void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
 {
-    if (scsi_req_enqueue(req->sreq)) {
-        scsi_req_continue(req->sreq);
+    SCSIRequest *sreq = req->sreq;
+    if (scsi_req_enqueue(sreq)) {
+        scsi_req_continue(sreq);
     }
-    bdrv_io_unplug(req->sreq->dev->conf.bs);
-    scsi_req_unref(req->sreq);
+    bdrv_io_unplug(sreq->dev->conf.bs);
+    scsi_req_unref(sreq);
 }
 
 static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)