diff mbox series

[v2,1/6] esp: don't underflow cmdfifo if no message out/command data is present

Message ID 20210317230223.24854-2-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
If a guest sends a TI (Transfer Information) command without previously sending
any message out/command phase data then cmdfifo will underflow triggering an
assert reading the IDENTIFY byte.

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

Comments

Alexander Bulekov March 17, 2021, 11:58 p.m. UTC | #1
On 210317 2302, Mark Cave-Ayland wrote:
> If a guest sends a TI (Transfer Information) command without previously sending
> any message out/command phase data then cmdfifo will underflow triggering an
> assert reading the IDENTIFY byte.
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1919035
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c | 22 ++++++++++++++--------
>  1 file changed, 14 insertions(+), 8 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 507ab363bc..5d3f1ccbc8 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -318,18 +318,24 @@  static void do_busid_cmd(ESPState *s, uint8_t busid)
 
 static void do_cmd(ESPState *s)
 {
-    uint8_t busid = fifo8_pop(&s->cmdfifo);
+    uint8_t busid;
     uint32_t n;
 
-    s->cmdfifo_cdb_offset--;
+    if (fifo8_num_used(&s->cmdfifo)) {
+        busid = fifo8_pop(&s->cmdfifo);
 
-    /* Ignore extended messages for now */
-    if (s->cmdfifo_cdb_offset) {
-        fifo8_pop_buf(&s->cmdfifo, s->cmdfifo_cdb_offset, &n);
-        s->cmdfifo_cdb_offset = 0;
-    }
+        if (s->cmdfifo_cdb_offset) {
+            s->cmdfifo_cdb_offset--;
+
+            /* Ignore extended messages for now */
+            if (s->cmdfifo_cdb_offset) {
+                fifo8_pop_buf(&s->cmdfifo, s->cmdfifo_cdb_offset, &n);
+                s->cmdfifo_cdb_offset = 0;
+            }
+        }
 
-    do_busid_cmd(s, busid);
+        do_busid_cmd(s, busid);
+    }
 }
 
 static void satn_pdma_cb(ESPState *s)