Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 83

kvm-83-164.el5_5.9.src.rpm

From ee741cdd6bc6f3b69dbde7950cb577f812ac0eba Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Thu, 4 Feb 2010 12:41:47 -0200
Subject: [PATCH] CVE-2010-0297: usb-linux.c: fix buffer overflow

RH-Author: Eduardo Habkost <ehabkost@redhat.com>
Message-id: <20100204124147.GY22381@blackpad.lan.raisama.net>
Patchwork-id: 6917
O-Subject: [PATCH KVM 5.5 5.4.z] CVE-2010-0297: usb-linux.c: fix buffer overflow
Bugzilla: 560770
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>
RH-Acked-by: Don Dutile <ddutile@redhat.com>

CVE: CVE-2010-0297
Bugzilla (5.5): https://bugzilla.redhat.com/show_bug.cgi?id=560770
Bugzilla (5.4.z): https://bugzilla.redhat.com/show_bug.cgi?id=560769

Backport of upstream commit:

commit c4c0e236beabb9de5ff472f77aeb811ec5484615
Author: Jim Paris <jim@jtan.com>
Date:   Mon Aug 24 14:56:12 2009 -0400

    usb-linux.c: fix buffer overflow

    In usb-linux.c:usb_host_handle_control, we pass a 1024-byte buffer and
    length to the kernel.  However, the length was provided by the caller
    of dev->handle_packet, and is not checked, so the kernel might provide
    too much data and overflow our buffer.

    For example, hw/usb-uhci.c could set the length to 2047.
    hw/usb-ohci.c looks like it might go up to 4096 or 8192.

    This causes a qemu crash, as reported here:
      http://www.mail-archive.com/kvm@vger.kernel.org/msg18447.html

    This patch increases the usb-linux.c buffer size to 2048 to fix the
    specific device reported, and adds a check to avoid the overflow in
    any case.

    Signed-off-by: Jim Paris <jim@jtan.com>
    Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Please ACK.

---
 qemu/usb-linux.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/usb-linux.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/qemu/usb-linux.c b/qemu/usb-linux.c
index bc7da67..7b0e729 100644
--- a/qemu/usb-linux.c
+++ b/qemu/usb-linux.c
@@ -119,7 +119,7 @@ struct ctrl_struct {
     uint16_t offset;
     uint8_t  state;
     struct   usb_ctrlrequest req;
-    uint8_t  buffer[1024];
+    uint8_t  buffer[2048];
 };
 
 typedef struct USBHostDevice {
@@ -560,6 +560,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
     struct usbdevfs_urb *urb;
     AsyncURB *aurb;
     int ret, value, index;
+    int buffer_len;
 
     /* 
      * Process certain standard device requests.
@@ -588,6 +589,13 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
 
     /* The rest are asynchronous */
 
+    buffer_len = 8 + s->ctrl.len;
+    if (buffer_len > sizeof(s->ctrl.buffer)) {
+	    fprintf(stderr, "husb: ctrl buffer too small (%u > %lu)\n",
+		    buffer_len, sizeof(s->ctrl.buffer));
+	    return USB_RET_STALL;
+    }
+
     aurb = async_alloc();
     if (!aurb) {
         dprintf("husb: async malloc failed\n");
@@ -608,7 +616,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
     urb->endpoint = p->devep;
 
     urb->buffer        = &s->ctrl.req;
-    urb->buffer_length = 8 + s->ctrl.len;
+    urb->buffer_length = buffer_len;
 
     urb->usercontext = s;
 
-- 
1.6.3.rc4.29.g8146