From patchwork Thu Nov 15 08:23:30 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 199220 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 85D6C2C00C1 for ; Thu, 15 Nov 2012 19:23:46 +1100 (EST) Received: from localhost ([::1]:46150 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYujg-0004K5-GJ for incoming@patchwork.ozlabs.org; Thu, 15 Nov 2012 03:23:44 -0500 Received: from eggs.gnu.org ([208.118.235.92]:50914) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYujW-0004JN-Qt for qemu-devel@nongnu.org; Thu, 15 Nov 2012 03:23:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TYujT-0005V0-Og for qemu-devel@nongnu.org; Thu, 15 Nov 2012 03:23:34 -0500 Received: from david.siemens.de ([192.35.17.14]:22864) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYujT-0005Uw-Eg for qemu-devel@nongnu.org; Thu, 15 Nov 2012 03:23:31 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by david.siemens.de (8.13.6/8.13.6) with ESMTP id qAF8NU8k025430; Thu, 15 Nov 2012 09:23:30 +0100 Received: from mchn199C.mchp.siemens.de ([139.22.116.190]) by mail1.siemens.de (8.13.6/8.13.6) with SMTP id qAF8NUU2010420; Thu, 15 Nov 2012 09:23:30 +0100 Message-ID: <50A4A682.2010508@siemens.com> Date: Thu, 15 Nov 2012 09:23:30 +0100 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Gerd Hoffmann X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 192.35.17.14 Cc: qemu-devel Subject: [Qemu-devel] [PATCH] usb: host-linux: Ignore parsing errors of the device descriptors X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The Linux is more tolerant here as well: Just stop parsing the device descriptors when an error is detected but do not reset what was found so far. This allows to run buggy devices with partially invalid descriptors. Signed-off-by: Jan Kiszka --- hw/usb/host-linux.c | 31 +++++++++++-------------------- 1 files changed, 11 insertions(+), 20 deletions(-) diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c index 3a258b4..b8127e1 100644 --- a/hw/usb/host-linux.c +++ b/hw/usb/host-linux.c @@ -135,7 +135,7 @@ static int parse_filter(const char *spec, struct USBAutoFilter *f); static void usb_host_auto_check(void *unused); static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name); -static int usb_linux_update_endp_table(USBHostDevice *s); +static void usb_linux_update_endp_table(USBHostDevice *s); static int usb_host_usbfs_type(USBHostDevice *s, USBPacket *p) { @@ -1122,8 +1122,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p, return USB_RET_ASYNC; } -/* returns 1 on problem encountered or 0 for success */ -static int usb_linux_update_endp_table(USBHostDevice *s) +static void usb_linux_update_endp_table(USBHostDevice *s) { static const char *tname[] = { [USB_ENDPOINT_XFER_CONTROL] = "control", @@ -1149,23 +1148,23 @@ static int usb_linux_update_endp_table(USBHostDevice *s) if (d->bLength < 2) { trace_usb_host_parse_error(s->bus_num, s->addr, "descriptor too short"); - goto error; + return; } if (i + d->bLength > s->descr_len) { trace_usb_host_parse_error(s->bus_num, s->addr, "descriptor too long"); - goto error; + return; } switch (d->bDescriptorType) { case 0: trace_usb_host_parse_error(s->bus_num, s->addr, "invalid descriptor type"); - goto error; + return; case USB_DT_DEVICE: if (d->bLength < 0x12) { trace_usb_host_parse_error(s->bus_num, s->addr, "device descriptor too short"); - goto error; + return; } v = (d->u.device.idVendor_hi << 8) | d->u.device.idVendor_lo; p = (d->u.device.idProduct_hi << 8) | d->u.device.idProduct_lo; @@ -1175,7 +1174,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) if (d->bLength < 0x09) { trace_usb_host_parse_error(s->bus_num, s->addr, "config descriptor too short"); - goto error; + return; } configuration = d->u.config.bConfigurationValue; active = (configuration == s->dev.configuration); @@ -1186,7 +1185,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) if (d->bLength < 0x09) { trace_usb_host_parse_error(s->bus_num, s->addr, "interface descriptor too short"); - goto error; + return; } interface = d->u.interface.bInterfaceNumber; altsetting = d->u.interface.bAlternateSetting; @@ -1199,7 +1198,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) if (d->bLength < 0x07) { trace_usb_host_parse_error(s->bus_num, s->addr, "endpoint descriptor too short"); - goto error; + return; } devep = d->u.endpoint.bEndpointAddress; pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT; @@ -1207,7 +1206,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) if (ep == 0) { trace_usb_host_parse_error(s->bus_num, s->addr, "invalid endpoint address"); - goto error; + return; } type = d->u.endpoint.bmAttributes & 0x3; @@ -1240,11 +1239,6 @@ static int usb_linux_update_endp_table(USBHostDevice *s) break; } } - return 0; - -error: - usb_ep_reset(&s->dev); - return 1; } /* @@ -1331,10 +1325,7 @@ static int usb_host_open(USBHostDevice *dev, int bus_num, } usb_ep_init(&dev->dev); - ret = usb_linux_update_endp_table(dev); - if (ret) { - goto fail; - } + usb_linux_update_endp_table(dev); if (speed == -1) { struct usbdevfs_connectinfo ci;