From patchwork Mon Mar 2 03:13:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adam Lee X-Patchwork-Id: 444905 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 92AD114010F; Mon, 2 Mar 2015 14:13:52 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1YSGnb-0001EG-Vg; Mon, 02 Mar 2015 03:13:39 +0000 Received: from mail-pa0-f46.google.com ([209.85.220.46]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1YSGnT-0001Dg-OO for kernel-team@lists.ubuntu.com; Mon, 02 Mar 2015 03:13:31 +0000 Received: by padbj1 with SMTP id bj1so14022882pad.11 for ; Sun, 01 Mar 2015 19:13:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=wWDGBFgM455pknvZlM8A7IAo/ts+VaDIaEYhHFoqKnU=; b=gjF3K3D2bSQkM+sLRtlvxDIKIj8ove7ypo17MK4MTD1ILbZMYMhBOx8pHh9KPfxvQ5 ZeXscX936dWwFI+rVhlw91wIVZyr8EhfX3PpV4lXGdvSK7q/S5owPuqjlUMrgO/OUT4m nftW0wtDTTMKjLHoX9RIx21W0Up5dEx2LkZ0+3VmkN+lzZHt2DT2t14PzMr3EPvO520r WyL3sXQ4JYk4xgTD3yWhkLFs9SaOnj8AslTh1qJLeEIRlinvgIYRuDO+6u3RpLUDBGl1 wwnUoYa4ji05qy/1KEGHDkjJW914vcAnE6xlzTOD++v1LaIoI9eZVh1LM1rpTF+Rt7a1 m7iw== X-Gm-Message-State: ALoCoQldrxiYFvGG0E3ci/XRNKodUuAY/zMHKwyWyxjW8P17F+wKbaP9pRcfHJIx5fxYmpAAIs/V X-Received: by 10.70.23.165 with SMTP id n5mr43099119pdf.60.1425266010957; Sun, 01 Mar 2015 19:13:30 -0800 (PST) Received: from localhost ([116.213.191.74]) by mx.google.com with ESMTPSA id qm12sm10329170pdb.36.2015.03.01.19.13.29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 01 Mar 2015 19:13:30 -0800 (PST) From: Adam Lee To: kernel-team@lists.ubuntu.com Subject: [PATCH Trusty/Utopic/Vivid] cdc-acm: add sanity checks Date: Mon, 2 Mar 2015 11:13:23 +0800 Message-Id: <1425266003-16279-1-git-send-email-adam.lee@canonical.com> X-Mailer: git-send-email 2.1.4 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Oliver Neukum BugLink: http://bugs.launchpad.net/bugs/1413992 Check the special CDC headers for a plausible minimum length. Another big operating systems ignores such garbage. Signed-off-by: Oliver Neukum CC: stable@vger.kernel.org Reviewed-by: Adam Lee Tested-by: Adam Lee Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 7e860a6e7aa62b337a61110430cd633db5b0d2dd) Signed-off-by: Adam Lee Acked-by: Andy Whitcroft --- drivers/usb/class/cdc-acm.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6746103..82dea40 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -943,6 +943,7 @@ static int acm_probe(struct usb_interface *intf, unsigned long quirks; int num_rx_buf; int i; + unsigned int elength = 0; int combined_interfaces = 0; struct device *tty_dev; int rv = -ENOMEM; @@ -988,9 +989,12 @@ static int acm_probe(struct usb_interface *intf, dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } + elength = buffer[0]; switch (buffer[2]) { case USB_CDC_UNION_TYPE: /* we've found it */ + if (elength < sizeof(struct usb_cdc_union_desc)) + goto next_desc; if (union_header) { dev_err(&intf->dev, "More than one " "union descriptor, skipping ...\n"); @@ -999,31 +1003,38 @@ static int acm_probe(struct usb_interface *intf, union_header = (struct usb_cdc_union_desc *)buffer; break; case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ + if (elength < sizeof(struct usb_cdc_country_functional_desc)) + goto next_desc; cfd = (struct usb_cdc_country_functional_desc *)buffer; break; case USB_CDC_HEADER_TYPE: /* maybe check version */ break; /* for now we ignore it */ case USB_CDC_ACM_TYPE: + if (elength < 4) + goto next_desc; ac_management_function = buffer[3]; break; case USB_CDC_CALL_MANAGEMENT_TYPE: + if (elength < 5) + goto next_desc; call_management_function = buffer[3]; call_interface_num = buffer[4]; if ((quirks & NOT_A_MODEM) == 0 && (call_management_function & 3) != 3) dev_err(&intf->dev, "This device cannot do calls on its own. It is not a modem.\n"); break; default: - /* there are LOTS more CDC descriptors that + /* + * there are LOTS more CDC descriptors that * could legitimately be found here. */ dev_dbg(&intf->dev, "Ignoring descriptor: " - "type %02x, length %d\n", - buffer[2], buffer[0]); + "type %02x, length %ud\n", + buffer[2], elength); break; } next_desc: - buflen -= buffer[0]; - buffer += buffer[0]; + buflen -= elength; + buffer += elength; } if (!union_header) {