diff mbox series

[v2,4/6] esp: don't underflow fifo when writing to the device

Message ID 20210317230223.24854-5-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series esp: fix asserts/segfaults discovered by fuzzer | expand

Commit Message

Mark Cave-Ayland March 17, 2021, 11:02 p.m. UTC
When writing to the device make sure that the fifo is not empty, otherwise the
fifo will underflow triggering an assert.

Buglink: https://bugs.launchpad.net/qemu/+bug/1909247
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

Comments

Alexander Bulekov March 18, 2021, 12:12 a.m. UTC | #1
On 210317 2302, Mark Cave-Ayland wrote:
> When writing to the device make sure that the fifo is not empty, otherwise the
> fifo will underflow triggering an assert.
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1909247
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c | 28 ++++++++++++++++------------
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 

Tested-by: Alexander Bulekov <alxndr@bu.edu>
diff mbox series

Patch

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index ae362c9dfb..bb57125035 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -509,18 +509,20 @@  static void do_dma_pdma_cb(ESPState *s)
         /* Copy FIFO data to device */
         len = MIN(s->async_len, ESP_FIFO_SZ);
         len = MIN(len, fifo8_num_used(&s->fifo));
-        memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
-        s->async_buf += n;
-        s->async_len -= n;
-        s->ti_size += n;
-
-        if (n < len) {
-            /* Unaligned accesses can cause FIFO wraparound */
-            len = len - n;
+        if (len) {
             memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
             s->async_buf += n;
             s->async_len -= n;
             s->ti_size += n;
+
+            if (n < len) {
+                /* Unaligned accesses can cause FIFO wraparound */
+                len = len - n;
+                memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
+                s->async_buf += n;
+                s->async_len -= n;
+                s->ti_size += n;
+            }
         }
 
         if (s->async_len == 0) {
@@ -730,10 +732,12 @@  static void esp_do_nodma(ESPState *s)
 
     if (to_device) {
         len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ);
-        memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
-        s->async_buf += len;
-        s->async_len -= len;
-        s->ti_size += len;
+        if (len) {
+            memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
+            s->async_buf += len;
+            s->async_len -= len;
+            s->ti_size += len;
+        }
     } else {
         len = MIN(s->ti_size, s->async_len);
         len = MIN(len, fifo8_num_free(&s->fifo));