CVE-2016-2538: Integer overflow in usb module (bz #1305815)

CVE-2016-2841: ne2000: infinite loop (bz #1304047)
CVE-2016-2857: net: out of bounds read (bz #1309564)
CVE-2016-2392: usb: null pointer dereference (bz #1307115)
spice: fix spice_chr_add_watch() crash (bz #1315049)
This commit is contained in:
Cole Robinson 2016-03-17 13:47:41 -04:00
parent db34050364
commit d62b5c0e5f
7 changed files with 275 additions and 1 deletions

View File

@ -0,0 +1,61 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 17 Feb 2016 00:23:40 +0530
Subject: [PATCH] usb: check RNDIS message length
When processing remote NDIS control message packets, the USB Net
device emulator uses a fixed length(4096) data buffer. The incoming
packet length could exceed this limit. Add a check to avoid it.
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455648821-17340-2-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 64c9bc181fc78275596649f591302d72df2d3071)
---
hw/usb/core.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/hw/usb/core.c b/hw/usb/core.c
index cf34755..f0201e3 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -128,9 +128,16 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
}
usb_packet_copy(p, s->setup_buf, p->iov.size);
+ s->setup_index = 0;
p->actual_length = 0;
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
- s->setup_index = 0;
+ if (s->setup_len > sizeof(s->data_buf)) {
+ fprintf(stderr,
+ "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
+ s->setup_len, sizeof(s->data_buf));
+ p->status = USB_RET_STALL;
+ return;
+ }
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
@@ -151,13 +158,6 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
}
s->setup_state = SETUP_STATE_DATA;
} else {
- if (s->setup_len > sizeof(s->data_buf)) {
- fprintf(stderr,
- "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
- s->setup_len, sizeof(s->data_buf));
- p->status = USB_RET_STALL;
- return;
- }
if (s->setup_len == 0)
s->setup_state = SETUP_STATE_ACK;
else
@@ -176,7 +176,7 @@ static void do_token_in(USBDevice *s, USBPacket *p)
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
-
+
switch(s->setup_state) {
case SETUP_STATE_ACK:
if (!(s->setup_buf[0] & USB_DIR_IN)) {

View File

@ -0,0 +1,56 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 17 Feb 2016 00:23:41 +0530
Subject: [PATCH] usb: check RNDIS buffer offsets & length
When processing remote NDIS control message packets,
the USB Net device emulator uses a fixed length(4096) data buffer.
The incoming informationBufferOffset & Length combination could
overflow and cross that range. Check control message buffer
offsets and length to avoid it.
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455648821-17340-3-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fe3c546c5ff2a6210f9a4d8561cc64051ca8603e)
---
hw/usb/dev-network.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 9be3a64..919ba2d 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -911,8 +911,9 @@ static int rndis_query_response(USBNetState *s,
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
buflen = le32_to_cpu(buf->InformationBufferLength);
- if (bufoffs + buflen > length)
+ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
return USB_RET_STALL;
+ }
infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
bufoffs + (uint8_t *) buf, buflen, infobuf,
@@ -957,8 +958,9 @@ static int rndis_set_response(USBNetState *s,
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
buflen = le32_to_cpu(buf->InformationBufferLength);
- if (bufoffs + buflen > length)
+ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
return USB_RET_STALL;
+ }
ret = ndis_set(s, le32_to_cpu(buf->OID),
bufoffs + (uint8_t *) buf, buflen);
@@ -1208,8 +1210,9 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
uint32_t size = le32_to_cpu(msg->DataLength);
- if (offs + size <= len)
+ if (offs < len && size < len && offs + size <= len) {
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, size);
+ }
}
s->out_ptr -= len;
memmove(s->out_buf, &s->out_buf[len], s->out_ptr);

View File

@ -0,0 +1,34 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 24 Feb 2016 11:41:33 +0530
Subject: [PATCH] net: ne2000: check ring buffer control registers
Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
bytes to process network packets. Registers PSTART & PSTOP
define ring buffer size & location. Setting these registers
to invalid values could lead to infinite loop or OOB r/w
access issues. Add check to avoid it.
Reported-by: Yang Hongke <yanghongke@huawei.com>
Tested-by: Yang Hongke <yanghongke@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 415ab35a441eca767d033a2702223e785b9d5190)
---
hw/net/ne2000.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 364f226..d196be6 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -154,6 +154,10 @@ static int ne2000_buffer_full(NE2000State *s)
{
int avail, index, boundary;
+ if (s->stop <= s->start) {
+ return 1;
+ }
+
index = s->curpag << 8;
boundary = s->boundary << 8;
if (index < boundary)

View File

@ -0,0 +1,44 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 2 Mar 2016 17:29:58 +0530
Subject: [PATCH] net: check packet payload length
While computing IP checksum, 'net_checksum_calculate' reads
payload length from the packet. It could exceed the given 'data'
buffer size. Add a check to avoid it.
Reported-by: Liu Ling <liuling-it@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 362786f14a753d8a5256ef97d7c10ed576d6572b)
---
net/checksum.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/checksum.c b/net/checksum.c
index 14c0855..0942437 100644
--- a/net/checksum.c
+++ b/net/checksum.c
@@ -59,6 +59,11 @@ void net_checksum_calculate(uint8_t *data, int length)
int hlen, plen, proto, csum_offset;
uint16_t csum;
+ /* Ensure data has complete L2 & L3 headers. */
+ if (length < 14 + 20) {
+ return;
+ }
+
if ((data[14] & 0xf0) != 0x40)
return; /* not IPv4 */
hlen = (data[14] & 0x0f) * 4;
@@ -76,8 +81,9 @@ void net_checksum_calculate(uint8_t *data, int length)
return;
}
- if (plen < csum_offset+2)
- return;
+ if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
+ return;
+ }
data[14+hlen+csum_offset] = 0;
data[14+hlen+csum_offset+1] = 0;

View File

@ -0,0 +1,32 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Thu, 11 Feb 2016 16:31:20 +0530
Subject: [PATCH] usb: check USB configuration descriptor object
When processing remote NDIS control message packets, the USB Net
device emulator checks to see if the USB configuration descriptor
object is of RNDIS type(2). But it does not check if it is null,
which leads to a null dereference error. Add check to avoid it.
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455188480-14688-1-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 80eecda8e5d09c442c24307f340840a5b70ea3b9)
---
hw/usb/dev-network.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 919ba2d..baf56b7 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -650,7 +650,8 @@ typedef struct USBNetState {
static int is_rndis(USBNetState *s)
{
- return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE;
+ return s->dev.config ?
+ s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE : 0;
}
static int ndis_query(USBNetState *s, uint32_t oid,

View File

@ -0,0 +1,29 @@
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
Date: Thu, 28 May 2015 15:04:58 +0200
Subject: [PATCH] spice: fix spice_chr_add_watch() pre-condition
Since e02bc6de30c44fd668dc0d6e1cd1804f2eed3ed3, add_watch() is called
with G_IO_HUP. Even if spice-qemu-char ignores this flag, the
precondition must be changed.
https://bugzilla.redhat.com/show_bug.cgi?id=1128992
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit f7a8beb5e6a13dc924895244777d9ef08b23b367)
---
spice-qemu-char.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index a4f4e57..4199bc2 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -169,7 +169,7 @@ static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond)
SpiceCharDriver *scd = chr->opaque;
SpiceCharSource *src;
- assert(cond == G_IO_OUT);
+ assert(cond & G_IO_OUT);
src = (SpiceCharSource *)g_source_new(&SpiceCharSourceFuncs,
sizeof(SpiceCharSource));

View File

@ -43,7 +43,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 2.3.1
Release: 12%{?dist}
Release: 13%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@ -165,6 +165,17 @@ Patch0046: 0046-target-ppc-kvm-fix-floating-point-registers-sync-on-.patch
# Fix qemu-img vmdk images to work with VMware (bz #1299185)
Patch0101: 0101-vmdk-Create-streamOptimized-as-version-3.patch
Patch0102: 0102-vmdk-Fix-converting-to-streamOptimized.patch
# CVE-2016-2538: Integer overflow in usb module (bz #1305815)
Patch0103: 0103-usb-check-RNDIS-message-length.patch
Patch0104: 0104-usb-check-RNDIS-buffer-offsets-length.patch
# CVE-2016-2841: ne2000: infinite loop (bz #1304047)
Patch0105: 0105-net-ne2000-check-ring-buffer-control-registers.patch
# CVE-2016-2857: net: out of bounds read (bz #1309564)
Patch0106: 0106-net-check-packet-payload-length.patch
# CVE-2016-2392: usb: null pointer dereference (bz #1307115)
Patch0107: 0107-usb-check-USB-configuration-descriptor-object.patch
# spice: fix spice_chr_add_watch() crash (bz #1315049)
Patch0108: 0108-spice-fix-spice_chr_add_watch-pre-condition.patch
BuildRequires: SDL2-devel
BuildRequires: zlib-devel
@ -1267,6 +1278,13 @@ getent passwd qemu >/dev/null || \
%changelog
* Thu Mar 17 2016 Cole Robinson <crobinso@redhat.com> - 2:2.3.1-13
- CVE-2016-2538: Integer overflow in usb module (bz #1305815)
- CVE-2016-2841: ne2000: infinite loop (bz #1304047)
- CVE-2016-2857: net: out of bounds read (bz #1309564)
- CVE-2016-2392: usb: null pointer dereference (bz #1307115)
- spice: fix spice_chr_add_watch() crash (bz #1315049)
* Mon Feb 15 2016 Cole Robinson <crobinso@redhat.com> - 2:2.3.1-12
- CVE-2015-8619: Fix sendkey out of bounds (bz #1292757)
- CVE-2016-1981: infinite loop in e1000 (bz #1299995)