From 1d6f884cfcfbf262dc041dee0095ea5f3c349c1f Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Mar 17 2016 17:09:54 +0000 Subject: 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) --- diff --git a/0103-usb-check-RNDIS-message-length.patch b/0103-usb-check-RNDIS-message-length.patch new file mode 100644 index 0000000..3cc986a --- /dev/null +++ b/0103-usb-check-RNDIS-message-length.patch @@ -0,0 +1,61 @@ +From: Prasad J Pandit +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 +Message-id: 1455648821-17340-2-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +(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 d0025db..7f46370 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)) { diff --git a/0104-usb-check-RNDIS-buffer-offsets-length.patch b/0104-usb-check-RNDIS-buffer-offsets-length.patch new file mode 100644 index 0000000..e989fec --- /dev/null +++ b/0104-usb-check-RNDIS-buffer-offsets-length.patch @@ -0,0 +1,56 @@ +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Message-id: 1455648821-17340-3-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +(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 7800cee..ba3c7a7 100644 +--- a/hw/usb/dev-network.c ++++ b/hw/usb/dev-network.c +@@ -914,8 +914,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, +@@ -960,8 +961,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); +@@ -1211,8 +1213,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); diff --git a/0105-net-ne2000-check-ring-buffer-control-registers.patch b/0105-net-ne2000-check-ring-buffer-control-registers.patch new file mode 100644 index 0000000..a6a4933 --- /dev/null +++ b/0105-net-ne2000-check-ring-buffer-control-registers.patch @@ -0,0 +1,34 @@ +From: Prasad J Pandit +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 +Tested-by: Yang Hongke +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +(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) diff --git a/0106-net-check-packet-payload-length.patch b/0106-net-check-packet-payload-length.patch new file mode 100644 index 0000000..a85831d --- /dev/null +++ b/0106-net-check-packet-payload-length.patch @@ -0,0 +1,44 @@ +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +(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; diff --git a/0107-usb-check-USB-configuration-descriptor-object.patch b/0107-usb-check-USB-configuration-descriptor-object.patch new file mode 100644 index 0000000..b5aeb24 --- /dev/null +++ b/0107-usb-check-USB-configuration-descriptor-object.patch @@ -0,0 +1,32 @@ +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Message-id: 1455188480-14688-1-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +(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 ba3c7a7..180adce 100644 +--- a/hw/usb/dev-network.c ++++ b/hw/usb/dev-network.c +@@ -653,7 +653,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, diff --git a/qemu.spec b/qemu.spec index 078defc..1f21465 100644 --- a/qemu.spec +++ b/qemu.spec @@ -40,7 +40,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 2.4.1 -Release: 7%{?dist} +Release: 8%{?dist} Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD Group: Development/Tools @@ -125,6 +125,15 @@ Patch0027: 0027-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 BuildRequires: SDL2-devel BuildRequires: zlib-devel @@ -1260,6 +1269,12 @@ getent passwd qemu >/dev/null || \ %changelog +* Thu Mar 17 2016 Cole Robinson - 2:2.4.1-8 +- 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) + * Mon Feb 15 2016 Cole Robinson - 2:2.4.1-7 - CVE-2015-8619: Fix sendkey out of bounds (bz #1292757) - CVE-2016-1981: infinite loop in e1000 (bz #1299995)