Fix SSE4 emulation with accel=tcg (bz #1270703)

CVE-2015-8345: Fix infinite loop in eepro100 (bz #1285214)
CVE-2015-7504: Fix heap overflow in pcnet (bz #1286543)
CVE-2015-7512: Fix buffer overflow in pcnet (bz #1286549)
This commit is contained in:
Cole Robinson 2015-12-07 14:03:07 -05:00
parent 2e7b59e5fe
commit 61dd8f57d1
5 changed files with 197 additions and 1 deletions

View File

@ -0,0 +1,40 @@
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Mon, 12 Oct 2015 11:50:27 +0200
Subject: [PATCH] target-i386: fix pcmpxstrx equal-ordered (strstr) mode
In this mode, referring an invalid element of the source forces the
result to false (table 4-7, last column) but referring an invalid
element of the destination forces the result to true, so the outer
loop should still be run even if some elements of the destination
will be invalid. They will be avoided in the inner loop, which
correctly bounds "i" to validd, but they will still contribute to a
positive outcome of the search.
This fixes tst_strstr in glibc 2.17.
Reported-by: Florian Weimer <fweimer@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 54c54f8b56047d3c2420e1ae06a6a8890c220ac4)
---
target-i386/ops_sse.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index bee134b..a9e1905 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -2037,10 +2037,10 @@ static inline unsigned pcmpxstrx(CPUX86State *env, Reg *d, Reg *s,
}
break;
case 3:
- for (j = valids - validd; j >= 0; j--) {
+ for (j = valids; j >= 0; j--) {
res <<= 1;
v = 1;
- for (i = MIN(upper - j, validd); i >= 0; i--) {
+ for (i = MIN(valids - j, validd); i >= 0; i--) {
v &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i));
}
res |= v;

View File

@ -0,0 +1,60 @@
From: Stefan Weil <sw@weilnetz.de>
Date: Fri, 20 Nov 2015 08:42:33 +0100
Subject: [PATCH] eepro100: Prevent two endless loops
http://lists.nongnu.org/archive/html/qemu-devel/2015-11/msg04592.html
shows an example how an endless loop in function action_command can
be achieved.
During my code review, I noticed a 2nd case which can result in an
endless loop.
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 00837731d254908a841d69298a4f9f077babaf24)
---
hw/net/eepro100.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 60333b7..685a478 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -774,6 +774,11 @@ static void tx_command(EEPRO100State *s)
#if 0
uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6);
#endif
+ if (tx_buffer_size == 0) {
+ /* Prevent an endless loop. */
+ logout("loop in %s:%u\n", __FILE__, __LINE__);
+ break;
+ }
tbd_address += 8;
TRACE(RXTX, logout
("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
@@ -855,6 +860,10 @@ static void set_multicast_list(EEPRO100State *s)
static void action_command(EEPRO100State *s)
{
+ /* The loop below won't stop if it gets special handcrafted data.
+ Therefore we limit the number of iterations. */
+ unsigned max_loop_count = 16;
+
for (;;) {
bool bit_el;
bool bit_s;
@@ -870,6 +879,13 @@ static void action_command(EEPRO100State *s)
#if 0
bool bit_sf = ((s->tx.command & COMMAND_SF) != 0);
#endif
+
+ if (max_loop_count-- == 0) {
+ /* Prevent an endless loop. */
+ logout("loop in %s:%u\n", __FILE__, __LINE__);
+ break;
+ }
+
s->cu_offset = s->tx.link;
TRACE(OTHER,
logout("val=(cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",

View File

@ -0,0 +1,47 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Fri, 20 Nov 2015 11:50:31 +0530
Subject: [PATCH] net: pcnet: add check to validate receive data
size(CVE-2015-7504)
In loopback mode, pcnet_receive routine appends CRC code to the
receive buffer. If the data size given is same as the buffer size,
the appended CRC code overwrites 4 bytes after s->buffer. Added a
check to avoid that.
Reported by: Qinghao Tang <luodalongde@gmail.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 837f21aacf5a714c23ddaadbbc5212f9b661e3f7)
---
hw/net/pcnet.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 3437376..4944444 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1085,7 +1085,7 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
uint32_t fcs = ~0;
uint8_t *p = src;
- while (p != &src[size-4])
+ while (p != &src[size])
CRC(fcs, *p++);
crc_err = (*(uint32_t *)p != htonl(fcs));
}
@@ -1234,8 +1234,10 @@ static void pcnet_transmit(PCNetState *s)
bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
/* if multi-tmd packet outsizes s->buffer then skip it silently.
- Note: this is not what real hw does */
- if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
+ * Note: this is not what real hw does.
+ * Last four bytes of s->buffer are used to store CRC FCS code.
+ */
+ if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) {
s->xmit_pos = -1;
goto txdone;
}

View File

@ -0,0 +1,34 @@
From: Jason Wang <jasowang@redhat.com>
Date: Mon, 30 Nov 2015 15:00:06 +0800
Subject: [PATCH] pcnet: fix rx buffer overflow(CVE-2015-7512)
Backends could provide a packet whose length is greater than buffer
size. Check for this and truncate the packet to avoid rx buffer
overflow in this case.
Cc: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 8b98a2f07175d46c3f7217639bd5e03f2ec56343)
---
hw/net/pcnet.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 4944444..27b7000 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1065,6 +1065,12 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
int pktcount = 0;
if (!s->looptest) {
+ if (size > 4092) {
+#ifdef PCNET_DEBUG_RMD
+ fprintf(stderr, "pcnet: truncates rx packet.\n");
+#endif
+ size = 4092;
+ }
memcpy(src, buf, size);
/* no need to compute the CRC */
src[size] = 0;

View File

@ -40,7 +40,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 2.4.1
Release: 1%{?dist}
Release: 2%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@ -68,6 +68,15 @@ Source12: bridge.conf
# qemu-kvm back compat wrapper
Source13: qemu-kvm.sh
# Fix SSE4 emulation with accel=tcg (bz #1270703)
Patch0001: 0001-target-i386-fix-pcmpxstrx-equal-ordered-strstr-mode.patch
# CVE-2015-8345: Fix infinite loop in eepro100 (bz #1285214)
Patch0002: 0002-eepro100-Prevent-two-endless-loops.patch
# CVE-2015-7504: Fix heap overflow in pcnet (bz #1286543)
Patch0003: 0003-net-pcnet-add-check-to-validate-receive-data-size-CV.patch
# CVE-2015-7512: Fix buffer overflow in pcnet (bz #1286549)
Patch0004: 0004-pcnet-fix-rx-buffer-overflow-CVE-2015-7512.patch
BuildRequires: SDL2-devel
BuildRequires: zlib-devel
BuildRequires: which
@ -1199,6 +1208,12 @@ getent passwd qemu >/dev/null || \
%changelog
* Mon Dec 07 2015 Cole Robinson <crobinso@redhat.com> - 2:2.4.1-2
- Fix SSE4 emulation with accel=tcg (bz #1270703)
- CVE-2015-8345: Fix infinite loop in eepro100 (bz #1285214)
- CVE-2015-7504: Fix heap overflow in pcnet (bz #1286543)
- CVE-2015-7512: Fix buffer overflow in pcnet (bz #1286549)
* Wed Nov 04 2015 Cole Robinson <crobinso@redhat.com> - 2:2.4.1-1
- Rebased to version 2.4.1