diff options
| author | Jim Paris | 2009-08-24 20:56:12 +0200 |
|---|---|---|
| committer | Anthony Liguori | 2009-09-11 17:19:42 +0200 |
| commit | c4c0e236beabb9de5ff472f77aeb811ec5484615 (patch) | |
| tree | 6b882b0014043282ce6cc361db0f8647fa98326e /usb-linux.c | |
| parent | Fix conditional compilation (MIPS host) (diff) | |
| download | qemu-c4c0e236beabb9de5ff472f77aeb811ec5484615.tar.gz qemu-c4c0e236beabb9de5ff472f77aeb811ec5484615.tar.xz qemu-c4c0e236beabb9de5ff472f77aeb811ec5484615.zip | |
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>
Diffstat (limited to 'usb-linux.c')
| -rw-r--r-- | usb-linux.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/usb-linux.c b/usb-linux.c index 01d145d173..c80499af94 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -115,7 +115,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 { @@ -552,6 +552,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. @@ -580,6 +581,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(); aurb->hdev = s; aurb->packet = p; @@ -596,7 +604,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; |
