Received: by 2002:a25:b323:0:0:0:0:0 with SMTP id l35csp362269ybj; Thu, 19 Sep 2019 15:45:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqwHX1SOi0Mu8ssYkn7qSF7m3OXNzg88jfozUdG98xNcFLwoBie/9sBb1jXu+BziiG9JEbhx X-Received: by 2002:a17:906:244c:: with SMTP id a12mr16153390ejb.288.1568933159238; Thu, 19 Sep 2019 15:45:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568933159; cv=none; d=google.com; s=arc-20160816; b=P7U77kQEuYoABj5AyGIo3XFhw1zIu0nj/x+s4w+7j4bbYvtBj7kAI+5XahRiJKxHc0 U9nfz+QSk9x2raDIsuFrq4qlWzft/XBNvB32DVrwgtqhqgYskUqWHs1t+RRuANo1N9Hx J8lBZBqzgedMVjLXvEN7HvaysQo1nxyJzI+gLTyC8Rs3j+fvdf063COm6A/eBWWYO6Yh vlk+QOH/nvI80tMvchph1tZ/c5QEp15vCx/Rw95s7dTqKw9nHimSZpseZGb7EzW7fB9b bEUZ/7TwjoFSdHK/nqOGaR/MzFkZtLqyuGNqFxgvvuJIU8zcoeGIWvY74ZVkP8/i7lo2 sR6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=BtzsBpB3iROuDZEbNrQHYZpuo6INQlLUWQDf/ArpX/U=; b=dsgdNa+eYeHA65Tloh5u3UKusUwva3SKI8pqeHWenZUHCkI/b5E0FK5FYEYqaHQ/f8 +0MNFqQs2fN4E/J+HwDhXuMDuq00AcO9beofoyioFPbSS3b7pt/Hw3dqrC87lM1WBmLx 2GLhX8oJWHa0NeZGTxnBkVsF3NpLRO1wG31SwyxLJ0tWxaMKwTvHnbTmQnWjLOwOoeSZ YxNHHGUZUBHxr3LxX41iuKsAVKq37gTJC/0RawnCVyhBHN+GQbk0wEZpdZZLwEQQlUIu joEoNeG8ljBio28Bd+e1WpZmX1Bl3D8lZyRBQ/c8IrWcvxH5NdJYXNE4Iu063asQRxI9 xzpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=yj8IxrMO; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s27si5380513ejb.356.2019.09.19.15.45.36; Thu, 19 Sep 2019 15:45:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=yj8IxrMO; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389023AbfISWNb (ORCPT + 99 others); Thu, 19 Sep 2019 18:13:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:52580 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732498AbfISWN1 (ORCPT ); Thu, 19 Sep 2019 18:13:27 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E61D621907; Thu, 19 Sep 2019 22:13:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568931206; bh=hHpqv0RpIw5uSzS46FkoM8KdEvq3EyzTdM8OwFRdj+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yj8IxrMOSHDGWtIHs6GdZaKod07n5QJ6Dnl3d0p1PPgr5813ILTJeOYwjRip2/gPZ P4kZpApUkqM7obinI/qqggKgp4oKwrig/QJY7r6HpmsrW9lZuzFg/RJWn6JWLnr6cY LBNb0Cu1/qYAPC0wrqe+DSqvGcMJXiPdUW8C0jZk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alan Stern , syzbot+35f4d916c623118d576e@syzkaller.appspotmail.com Subject: [PATCH 4.19 06/79] USB: usbcore: Fix slab-out-of-bounds bug during device reset Date: Fri, 20 Sep 2019 00:02:51 +0200 Message-Id: <20190919214808.263409321@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190919214807.612593061@linuxfoundation.org> References: <20190919214807.612593061@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alan Stern commit 3dd550a2d36596a1b0ee7955da3b611c031d3873 upstream. The syzbot fuzzer provoked a slab-out-of-bounds error in the USB core: BUG: KASAN: slab-out-of-bounds in memcmp+0xa6/0xb0 lib/string.c:904 Read of size 1 at addr ffff8881d175bed6 by task kworker/0:3/2746 CPU: 0 PID: 2746 Comm: kworker/0:3 Not tainted 5.3.0-rc5+ #28 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: usb_hub_wq hub_event Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xca/0x13e lib/dump_stack.c:113 print_address_description+0x6a/0x32c mm/kasan/report.c:351 __kasan_report.cold+0x1a/0x33 mm/kasan/report.c:482 kasan_report+0xe/0x12 mm/kasan/common.c:612 memcmp+0xa6/0xb0 lib/string.c:904 memcmp include/linux/string.h:400 [inline] descriptors_changed drivers/usb/core/hub.c:5579 [inline] usb_reset_and_verify_device+0x564/0x1300 drivers/usb/core/hub.c:5729 usb_reset_device+0x4c1/0x920 drivers/usb/core/hub.c:5898 rt2x00usb_probe+0x53/0x7af drivers/net/wireless/ralink/rt2x00/rt2x00usb.c:806 The error occurs when the descriptors_changed() routine (called during a device reset) attempts to compare the old and new BOS and capability descriptors. The length it uses for the comparison is the wTotalLength value stored in BOS descriptor, but this value is not necessarily the same as the length actually allocated for the descriptors. If it is larger the routine will call memcmp() with a length that is too big, thus reading beyond the end of the allocated region and leading to this fault. The kernel reads the BOS descriptor twice: first to get the total length of all the capability descriptors, and second to read it along with all those other descriptors. A malicious (or very faulty) device may send different values for the BOS descriptor fields each time. The memory area will be allocated using the wTotalLength value read the first time, but stored within it will be the value read the second time. To prevent this possibility from causing any errors, this patch modifies the BOS descriptor after it has been read the second time: It sets the wTotalLength field to the actual length of the descriptors that were read in and validated. Then the memcpy() call, or any other code using these descriptors, will be able to rely on wTotalLength being valid. Reported-and-tested-by: syzbot+35f4d916c623118d576e@syzkaller.appspotmail.com Signed-off-by: Alan Stern CC: Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1909041154260.1722-100000@iolanthe.rowland.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -925,7 +925,7 @@ int usb_get_bos_descriptor(struct usb_de struct usb_bos_descriptor *bos; struct usb_dev_cap_header *cap; struct usb_ssp_cap_descriptor *ssp_cap; - unsigned char *buffer; + unsigned char *buffer, *buffer0; int length, total_len, num, i, ssac; __u8 cap_type; int ret; @@ -970,10 +970,12 @@ int usb_get_bos_descriptor(struct usb_de ret = -ENOMSG; goto err; } + + buffer0 = buffer; total_len -= length; + buffer += length; for (i = 0; i < num; i++) { - buffer += length; cap = (struct usb_dev_cap_header *)buffer; if (total_len < sizeof(*cap) || total_len < cap->bLength) { @@ -987,8 +989,6 @@ int usb_get_bos_descriptor(struct usb_de break; } - total_len -= length; - if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { dev_warn(ddev, "descriptor type invalid, skip\n"); continue; @@ -1023,7 +1023,11 @@ int usb_get_bos_descriptor(struct usb_de default: break; } + + total_len -= length; + buffer += length; } + dev->bos->desc->wTotalLength = cpu_to_le16(buffer - buffer0); return 0;