From patchwork Thu Sep 28 10:16:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaejoong Kim X-Patchwork-Id: 9975711 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9F517603F2 for ; Thu, 28 Sep 2017 10:17:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8EDBE2954B for ; Thu, 28 Sep 2017 10:17:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7DA1F29551; Thu, 28 Sep 2017 10:17:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 156C02954B for ; Thu, 28 Sep 2017 10:17:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751524AbdI1KQp (ORCPT ); Thu, 28 Sep 2017 06:16:45 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:35773 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751129AbdI1KQo (ORCPT ); Thu, 28 Sep 2017 06:16:44 -0400 Received: by mail-pf0-f196.google.com with SMTP id i23so1109346pfi.2; Thu, 28 Sep 2017 03:16:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QAHcoz0fkUiJWBGvwIenXihkmRyWBS5FnYTs0ToFuT0=; b=XEWYFDplNndQSGI/L+P/0MRHkgathAILbqMLpgTF3EOdnqsSV/tj0wmE61Ogss0Cmh UXrlfQwI6PbGxE1POa52V+sqbGUk0BdVn63/aD7KsAe9hKD+AeuVGGX8LkVag0YtUSRT 1BTTvUNRz63OBDUCuKSeXDuu9RUX9Af92GTOdDBvCBHNSnbTiEuMkUSChetel1wA5kji JJoJimSVQ++cSAKDbcl44tGSqsj/0N4+qwS4BuD0YzmKRZunvM9B3y28yIZatvNRjmbP S/jij9k5RZhUPJIR95zNm76pht0dTBFQ+PsiSVfzXXyg7yknFjizpNUatnVrYBuHNUB6 2mrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QAHcoz0fkUiJWBGvwIenXihkmRyWBS5FnYTs0ToFuT0=; b=g2SE6Apib+fkbUMCaQ5B6GevBC5POYCiXXBjv2etp25O5uhyDr0nSy/Dd5DSJjkQ3b s/N5J4G0H2uiLZdy4i81dHlWbjzYWA0G7N7U8esM4iDQERBLEAWU02Bb8HjPWSWomYQ5 W5c4ahCuU7JxPmwPtzeXHQ8Q2hU1T/7eY45BVfY/nme2dRh54PXFqzYUouauqM6XLZyQ pPPH8henUfXngSJuhFdIej48G9ps5IM5POnWhSBentse7tKqsVrHqcKHXW9NvgQ4jxDu HnFzaPuT/n70zOspY1B0q+1UH5w5jkTY7UZG+pH7UPslTljQh0gRQO3QBNtIpHRXs7YA wfhQ== X-Gm-Message-State: AHPjjUgBbJwFclbm+da8u3TqZ4mooMvOUlX+JhbN44ZpGDvRK+HC+uTc b0keYhkRQBeRPeuIM5xl+ZI= X-Google-Smtp-Source: AOwi7QC8RKmf9iyPZC50rSH3yCJOQa0yWp3DhBXBrVZEtDIn8W9EpLZ8ODC/W6xTjymTag8b6eryig== X-Received: by 10.101.75.136 with SMTP id t8mr3812998pgq.282.1506593803526; Thu, 28 Sep 2017 03:16:43 -0700 (PDT) Received: from localhost.localdomain ([27.122.242.72]) by smtp.gmail.com with ESMTPSA id f10sm2405657pgr.67.2017.09.28.03.16.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 Sep 2017 03:16:42 -0700 (PDT) From: Jaejoong Kim To: Alan Stern , Jiri Kosina Cc: Andrey Konovalov , Benjamin Tissoires , USB list , linux-input@vger.kernel.org, LKML , syzkaller , Jaejoong Kim Subject: [PATCH v2] HID: usbhid: fix out-of-bounds bug Date: Thu, 28 Sep 2017 19:16:30 +0900 Message-Id: <1506593790-19865-1-git-send-email-climbbb.kim@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The hid descriptor identifies the length and type of subordinate descriptors for a device. If the received hid descriptor is smaller than the size of the struct hid_descriptor, it is possible to cause out-of-bounds. In addition, if bNumDescriptors of the hid descriptor have an incorrect value, this can also cause out-of-bounds while approaching hdesc->desc[n]. So check the size of hid descriptor and bNumDescriptors. BUG: KASAN: slab-out-of-bounds in usbhid_parse+0x9b1/0xa20 Read of size 1 at addr ffff88006c5f8edf by task kworker/1:2/1261 CPU: 1 PID: 1261 Comm: kworker/1:2 Not tainted 4.14.0-rc1-42251-gebb2c2437d80 #169 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Workqueue: usb_hub_wq hub_event Call Trace: __dump_stack lib/dump_stack.c:16 dump_stack+0x292/0x395 lib/dump_stack.c:52 print_address_description+0x78/0x280 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 kasan_report+0x22f/0x340 mm/kasan/report.c:409 __asan_report_load1_noabort+0x19/0x20 mm/kasan/report.c:427 usbhid_parse+0x9b1/0xa20 drivers/hid/usbhid/hid-core.c:1004 hid_add_device+0x16b/0xb30 drivers/hid/hid-core.c:2944 usbhid_probe+0xc28/0x1100 drivers/hid/usbhid/hid-core.c:1369 usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361 really_probe drivers/base/dd.c:413 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523 device_add+0xd0b/0x1660 drivers/base/core.c:1835 usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932 generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174 usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266 really_probe drivers/base/dd.c:413 driver_probe_device+0x610/0xa00 drivers/base/dd.c:557 __device_attach_driver+0x230/0x290 drivers/base/dd.c:653 bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463 __device_attach+0x26e/0x3d0 drivers/base/dd.c:710 device_initial_probe+0x1f/0x30 drivers/base/dd.c:757 bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523 device_add+0xd0b/0x1660 drivers/base/core.c:1835 usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457 hub_port_connect drivers/usb/core/hub.c:4903 hub_port_connect_change drivers/usb/core/hub.c:5009 port_event drivers/usb/core/hub.c:5115 hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195 process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119 worker_thread+0x221/0x1850 kernel/workqueue.c:2253 kthread+0x3a1/0x470 kernel/kthread.c:231 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 Reported-by: Andrey Konovalov Signed-off-by: Jaejoong Kim Tested-by: Andrey Konovalov Acked-by: Alan Stern --- Changes in v2: - write a new commit message because orginal version is wrong approach - add check hid descriptor size - get proper value for bNumDescriptors as suggested by Alan Stern - fix the Reported-by drivers/hid/usbhid/hid-core.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 089bad8..045b5da 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -975,6 +975,8 @@ static int usbhid_parse(struct hid_device *hid) unsigned int rsize = 0; char *rdesc; int ret, n; + int num_descriptors; + size_t offset = offsetof(struct hid_descriptor, desc); quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); @@ -997,10 +999,18 @@ static int usbhid_parse(struct hid_device *hid) return -ENODEV; } + if (hdesc->bLength < sizeof(struct hid_descriptor)) { + dbg_hid("hid descriptor is too short\n"); + return -EINVAL; + } + hid->version = le16_to_cpu(hdesc->bcdHID); hid->country = hdesc->bCountryCode; - for (n = 0; n < hdesc->bNumDescriptors; n++) + num_descriptors = min_t(int, hdesc->bNumDescriptors, + (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); + + for (n = 0; n < num_descriptors; n++) if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);