From: Paolo Bonzini <[email protected]> Reentrant MMIO can cause the SCSIRequest to be completed, at which point lsi_request_orphan would drop the last reference. Anything that happens afterwards would access freed data. Keep a reference to the SCSIRequest and, through req->hba_private, to the lsi_request* for as long as DMA runs.
Reported-by: Jihe Wang <[email protected]> Cc: [email protected] Signed-off-by: Paolo Bonzini <[email protected]> (cherry picked from commit d459131ff590c517bc89fa5867d4878b5eacbc30) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 5e9321f1a2..c845e0bee7 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -637,7 +637,7 @@ static void lsi_do_dma(LSIState *s, int out) } p = s->current; - req = s->current->req; + req = scsi_req_ref(s->current->req); dev = req->dev; assert(dev); @@ -667,6 +667,11 @@ static void lsi_do_dma(LSIState *s, int out) } else { lsi_mem_write(s, addr, p->dma_buf, count); } + if (p->orphan) { + scsi_req_unref(req); + return; + } + scsi_req_unref(req); p->dma_len -= count; if (p->dma_len == 0) { -- 2.47.3
