Commit 5519724a authored by Mauro Matteo Cascella's avatar Mauro Matteo Cascella Committed by Jason Wang
Browse files

hw/net/xgmac: Fix buffer overflow in xgmac_enet_send()



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: default avatarZiming Zhang <ezrakiez@gmail.com>
Signed-off-by: default avatarMauro Matteo Cascella <mcascell@redhat.com>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
parent e219d309
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -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);