|
|
34b321 |
From dc546cbfdefb8ddbaf121d3b075ca723df264d1c Mon Sep 17 00:00:00 2001
|
|
|
34b321 |
From: Vlad Yasevich <vyasevic@redhat.com>
|
|
|
34b321 |
Date: Wed, 16 Dec 2015 02:58:22 +0100
|
|
|
34b321 |
Subject: [PATCH 5/6] rtl8139: Fix receive buffer overflow check
|
|
|
34b321 |
|
|
|
34b321 |
Message-id: <1450234703-7606-2-git-send-email-vyasevic@redhat.com>
|
|
|
34b321 |
Patchwork-id: 68617
|
|
|
34b321 |
O-Subject: [RHEL7.3 qemu-kvm PATCH 1/2] rtl8139: Fix receive buffer overflow check
|
|
|
34b321 |
Bugzilla: 1252757
|
|
|
34b321 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
34b321 |
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
34b321 |
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
|
|
34b321 |
|
|
|
34b321 |
rtl8139_do_receive() tries to check for the overflow condition
|
|
|
34b321 |
by making sure that packet_size + 8 does not exceed the
|
|
|
34b321 |
available buffer space. The issue here is that RxBuffAddr,
|
|
|
34b321 |
used to calculate available buffer space, is aligned to a
|
|
|
34b321 |
a 4 byte boundry after every update. So it is possible that
|
|
|
34b321 |
every packet ends up being slightly padded when written
|
|
|
34b321 |
to the receive buffer. This padding is not taken into
|
|
|
34b321 |
account when checking for overflow and we may end up missing
|
|
|
34b321 |
the overflow condition can causing buffer overwrite.
|
|
|
34b321 |
|
|
|
34b321 |
This patch takes alignment into consideration when
|
|
|
34b321 |
checking for overflow condition.
|
|
|
34b321 |
|
|
|
34b321 |
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
|
|
34b321 |
Reviewed-by: Jason Wang <jasowang@redhat.com>
|
|
|
34b321 |
Message-id: 1441121206-6997-2-git-send-email-vyasevic@redhat.com
|
|
|
34b321 |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
34b321 |
(cherry picked from commit fabdcd3392f16fc666b1d04fc1bbe5f1dbbf10a4)
|
|
|
34b321 |
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
|
|
|
34b321 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
34b321 |
---
|
|
|
34b321 |
hw/net/rtl8139.c | 6 ++++--
|
|
|
34b321 |
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
34b321 |
|
|
|
34b321 |
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
|
|
|
34b321 |
index 4f89328..6a167df 100644
|
|
|
34b321 |
--- a/hw/net/rtl8139.c
|
|
|
34b321 |
+++ b/hw/net/rtl8139.c
|
|
|
34b321 |
@@ -1137,7 +1137,9 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
|
|
|
34b321 |
|
|
|
34b321 |
/* if receiver buffer is empty then avail == 0 */
|
|
|
34b321 |
|
|
|
34b321 |
- if (avail != 0 && size + 8 >= avail)
|
|
|
34b321 |
+#define RX_ALIGN(x) (((x) + 3) & ~0x3)
|
|
|
34b321 |
+
|
|
|
34b321 |
+ if (avail != 0 && RX_ALIGN(size + 8) >= avail)
|
|
|
34b321 |
{
|
|
|
34b321 |
DPRINTF("rx overflow: rx buffer length %d head 0x%04x "
|
|
|
34b321 |
"read 0x%04x === available 0x%04x need 0x%04x\n",
|
|
|
34b321 |
@@ -1165,7 +1167,7 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t
|
|
|
34b321 |
rtl8139_write_buffer(s, (uint8_t *)&val, 4);
|
|
|
34b321 |
|
|
|
34b321 |
/* correct buffer write pointer */
|
|
|
34b321 |
- s->RxBufAddr = MOD2((s->RxBufAddr + 3) & ~0x3, s->RxBufferSize);
|
|
|
34b321 |
+ s->RxBufAddr = MOD2(RX_ALIGN(s->RxBufAddr), s->RxBufferSize);
|
|
|
34b321 |
|
|
|
34b321 |
/* now we can signal we have received something */
|
|
|
34b321 |
|
|
|
34b321 |
--
|
|
|
34b321 |
1.8.3.1
|
|
|
34b321 |
|