aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-09-15 13:03:53 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-09-15 13:03:53 +0100
commitb76a0d5db25ad9f81346930230092fdf1e88a5a1 (patch)
tree3ade1880580bc2b14c7a64c25221a79bb85a1874
parent007e620a7576e4ce2ea6955541e87d8ae8ed32ae (diff)
parent737d2b3c41d59eb8f94ab7eb419b957938f24943 (diff)
Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
This net pull request contains security fixes for qemu.git/master. The patches should also be applied to stable trees. The ne2000 NIC model has QEMU memory corruption issue. Both ne2000 and e1000 have an infinite loop. Please see the patches for CVE numbers and details on the bugs. # gpg: Signature made Tue 15 Sep 2015 13:02:21 BST using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" * remotes/stefanha/tags/net-pull-request: net: avoid infinite loop when receiving packets(CVE-2015-5278) net: add checks to validate ring buffer pointers(CVE-2015-5279) e1000: Avoid infinite loop in processing transmit descriptor (CVE-2015-6815) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/net/e1000.c3
-rw-r--r--hw/net/ne2000.c21
2 files changed, 18 insertions, 6 deletions
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 5c6bcd0014..09c9e9d53b 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -740,7 +740,8 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
memmove(tp->data, tp->header, tp->hdr_len);
tp->size = tp->hdr_len;
}
- } while (split_size -= bytes);
+ split_size -= bytes;
+ } while (bytes && split_size);
} else if (!tp->tse && tp->cptse) {
// context descriptor TSE is not set, while data descriptor TSE is set
DBGOUT(TXERR, "TCP segmentation error\n");
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 53c704ad41..010f9efccd 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -221,6 +221,9 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
}
index = s->curpag << 8;
+ if (index >= NE2000_PMEM_END) {
+ index = s->start;
+ }
/* 4 bytes for header */
total_len = size + 4;
/* address for next packet (4 bytes for CRC) */
@@ -244,7 +247,7 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
if (index <= s->stop)
avail = s->stop - index;
else
- avail = 0;
+ break;
len = size;
if (len > avail)
len = avail;
@@ -306,13 +309,19 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
offset = addr | (page << 4);
switch(offset) {
case EN0_STARTPG:
- s->start = val << 8;
+ if (val << 8 <= NE2000_PMEM_END) {
+ s->start = val << 8;
+ }
break;
case EN0_STOPPG:
- s->stop = val << 8;
+ if (val << 8 <= NE2000_PMEM_END) {
+ s->stop = val << 8;
+ }
break;
case EN0_BOUNDARY:
- s->boundary = val;
+ if (val << 8 < NE2000_PMEM_END) {
+ s->boundary = val;
+ }
break;
case EN0_IMR:
s->imr = val;
@@ -353,7 +362,9 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->phys[offset - EN1_PHYS] = val;
break;
case EN1_CURPAG:
- s->curpag = val;
+ if (val << 8 < NE2000_PMEM_END) {
+ s->curpag = val;
+ }
break;
case EN1_MULT ... EN1_MULT + 7:
s->mult[offset - EN1_MULT] = val;