summaryrefslogtreecommitdiffstats
path: root/hw/net
diff options
context:
space:
mode:
authorMauro Matteo Cascella2020-07-10 11:19:41 +0200
committerJason Wang2020-07-21 15:30:39 +0200
commit5519724a13664b43e225ca05351c60b4468e4555 (patch)
tree401da5be376e55b6477d4bc67eabe244443b28dd /hw/net
parenthw/net: Added plen fix for IPv6 (diff)
downloadqemu-5519724a13664b43e225ca05351c60b4468e4555.tar.gz
qemu-5519724a13664b43e225ca05351c60b4468e4555.tar.xz
qemu-5519724a13664b43e225ca05351c60b4468e4555.zip
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: Ziming Zhang <ezrakiez@gmail.com> Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net')
-rw-r--r--hw/net/xgmac.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index 574dd47b41..5bf1b61012 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -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);