aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2021-04-07 20:57:50 +0100
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2021-04-12 22:33:33 +0100
commit0db895361b8a82e1114372ff9f4857abea605701 (patch)
tree6c514a31795869d238bdd17660281f679ecfa882
parentff4a1daba6adc8811efb5046483feb3af6bd8d83 (diff)
downloadqemu-0db895361b8a82e1114372ff9f4857abea605701.zip
qemu-0db895361b8a82e1114372ff9f4857abea605701.tar.gz
qemu-0db895361b8a82e1114372ff9f4857abea605701.tar.bz2
esp: always check current_req is not NULL before use in DMA callbacks
After issuing a SCSI command the SCSI layer can call the SCSIBusInfo .cancel callback which resets both current_req and current_dev to NULL. If any data is left in the transfer buffer (async_len != 0) then the next TI (Transfer Information) command will attempt to reference the NULL pointer causing a segfault. Buglink: https://bugs.launchpad.net/qemu/+bug/1910723 Buglink: https://bugs.launchpad.net/qemu/+bug/1909247 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-2-mark.cave-ayland@ilande.co.uk>
-rw-r--r--hw/scsi/esp.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index d87e1a6..a79196f 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -496,6 +496,10 @@ static void do_dma_pdma_cb(ESPState *s)
return;
}
+ if (!s->current_req) {
+ return;
+ }
+
if (to_device) {
/* Copy FIFO data to device */
len = MIN(s->async_len, ESP_FIFO_SZ);
@@ -527,11 +531,9 @@ static void do_dma_pdma_cb(ESPState *s)
return;
} else {
if (s->async_len == 0) {
- if (s->current_req) {
- /* Defer until the scsi layer has completed */
- scsi_req_continue(s->current_req);
- s->data_in_ready = false;
- }
+ /* Defer until the scsi layer has completed */
+ scsi_req_continue(s->current_req);
+ s->data_in_ready = false;
return;
}
@@ -604,6 +606,9 @@ static void esp_do_dma(ESPState *s)
}
return;
}
+ if (!s->current_req) {
+ return;
+ }
if (s->async_len == 0) {
/* Defer until data is available. */
return;
@@ -713,6 +718,10 @@ static void esp_do_nodma(ESPState *s)
return;
}
+ if (!s->current_req) {
+ return;
+ }
+
if (s->async_len == 0) {
/* Defer until data is available. */
return;