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>
This commit is contained in:
Mark Cave-Ayland 2021-04-07 20:57:50 +01:00
parent ff4a1daba6
commit 0db895361b

View File

@ -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;