]> Git Repo - qemu.git/commitdiff
hw/net/xgmac: Fix buffer overflow in xgmac_enet_send()
authorMauro Matteo Cascella <[email protected]>
Fri, 10 Jul 2020 09:19:41 +0000 (11:19 +0200)
committerJason Wang <[email protected]>
Tue, 21 Jul 2020 13:30:39 +0000 (21:30 +0800)
A buffer overflow issue was reported by Mr. Ziming Zhang, CC'd here. It
occurs while sending an Ethernet frame due to missing break statements
and improper checking of the buffer size.

Reported-by: Ziming Zhang <[email protected]>
Signed-off-by: Mauro Matteo Cascella <[email protected]>
Reviewed-by: Peter Maydell <[email protected]>
Signed-off-by: Jason Wang <[email protected]>
hw/net/xgmac.c

index 574dd47b412fef025943f8e4b8be23bd6829db02..5bf1b6101242d0922ece06ec50fc5e877bce0314 100644 (file)
@@ -220,21 +220,31 @@ static void xgmac_enet_send(XgmacState *s)
         }
         len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff);
 
+        /*
+         * FIXME: these cases of malformed tx descriptors (bad sizes)
+         * should probably be reported back to the guest somehow
+         * rather than simply silently stopping processing, but we
+         * don't know what the hardware does in this situation.
+         * This will only happen for buggy guests anyway.
+         */
         if ((bd.buffer1_size & 0xfff) > 2048) {
             DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
                         "xgmac buffer 1 len on send > 2048 (0x%x)\n",
                          __func__, bd.buffer1_size & 0xfff);
+            break;
         }
         if ((bd.buffer2_size & 0xfff) != 0) {
             DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
                         "xgmac buffer 2 len on send != 0 (0x%x)\n",
                         __func__, bd.buffer2_size & 0xfff);
+            break;
         }
-        if (len >= sizeof(frame)) {
+        if (frame_size + len >= sizeof(frame)) {
             DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu "
-                        "buffer\n" , __func__, len, sizeof(frame));
+                        "buffer\n" , __func__, frame_size + len, sizeof(frame));
             DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n",
                         __func__, bd.buffer1_size, bd.buffer2_size);
+            break;
         }
 
         cpu_physical_memory_read(bd.buffer1_addr, ptr, len);
This page took 0.028342 seconds and 4 git commands to generate.