Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp3579333pxb; Mon, 24 Jan 2022 12:41:52 -0800 (PST) X-Google-Smtp-Source: ABdhPJxFUapygGUTsVZD1QNtgdatZ1/ZVBMw/aak/PyDHVI0O+4ojcvB4A2EDH1eU39eGYqoWuCR X-Received: by 2002:a05:6a00:140e:b0:4c5:75b4:d522 with SMTP id l14-20020a056a00140e00b004c575b4d522mr15693068pfu.45.1643056912092; Mon, 24 Jan 2022 12:41:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643056912; cv=none; d=google.com; s=arc-20160816; b=o1IjDD7tD6DoTY5Fuv4/5r4rcUci84xz3bJV2bOZqY9aHZ1OI0gjfhnBbvN+84VYoC idMLhACa6UqFv+FNY6hf9GbY99nULi2QOvnGKMd21ronOzyPNwPP7JzRerbB9CnIvn7x QUF93hUUwZn8nPxdFW3J5PDvnhqugYSS+cbpGFSaQ2Cu+tuj7sdXXCh1AsWDElSd3SKQ szcG0CtgI+UVXCUm+CO/kDU5Ccch7b91VjX+Wcv/8d4a8EzM3crmOHGhjIWCTxWVgWeR M8hBXBxsvtq0c3eOMa4wG+L83CtoKJqTKRoOYLMJSeK/zyVPbJK0qxEcE4JyUFSLIE5G zlmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qeI2TcQnbTXSMhCQ2vYldO1Kg+P1N2OGZPB/sf2N5Ps=; b=uh630e4IqqUAnqcoHDw2JHLg8E0r+Q1nfipIHVtV4mccW4XvYklxxbTcUSWC2HMD2M xvnTbEOzc6VyN73Y6jDA3ENIKX1jp3qGH2JatS0g9rGkRS4faJJu+JqZfQaEcKDrQjsv qVLiwgyY7DRUhAvqd8S+lSmpdEce/sRkGnvxxi5jTu17W/zmb7m1W3c3SB5581beLRc7 pMAvdzAN6QA3gWbPffrG9/5T7IXo/35/v/dNdNav9zL1ry3JYhTA6Os+Fi/FbFT1LmaD 1xZ7zc2dAaPfh99ql9THkdVVRT8IpWg76Tv8ZjdefyjSwgw05ysDM+PrKcwPAps4A9hx GCqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=zIeUZW2P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p13si6224864plf.137.2022.01.24.12.41.37; Mon, 24 Jan 2022 12:41:52 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=zIeUZW2P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355335AbiAXT5p (ORCPT + 99 others); Mon, 24 Jan 2022 14:57:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345107AbiAXT3L (ORCPT ); Mon, 24 Jan 2022 14:29:11 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AAFD3C061370; Mon, 24 Jan 2022 11:13:33 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 5C617B811FC; Mon, 24 Jan 2022 19:13:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 80F64C340E5; Mon, 24 Jan 2022 19:13:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643051611; bh=ZfBUl0u5AfHOOTBI41FpO7qivmtViI+G6jcWj/wLIu4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zIeUZW2P4QKJrSLb1ELMJlUu9iwJ5jOsjBWo8Yr0q2mZPU/mvoj3kUr6F2HZszfi1 7fbCwnXvFsM+zepybK9Qc4M40tUJRKL7j0zKsytwC01H9cHayjZpwRb3uzE33v2F1k Dav47Ajew46a/tyTJi5Mu60MxAM+ZWYlSApUGeZs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alan Stern , syzbot+3ae6a2b06f131ab9849f@syzkaller.appspotmail.com Subject: [PATCH 4.19 003/239] USB: Fix "slab-out-of-bounds Write" bug in usb_hcd_poll_rh_status Date: Mon, 24 Jan 2022 19:40:41 +0100 Message-Id: <20220124183943.223398994@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220124183943.102762895@linuxfoundation.org> References: <20220124183943.102762895@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alan Stern commit 1d7d4c07932e04355d6e6528d44a2f2c9e354346 upstream. When the USB core code for getting root-hub status reports was originally written, it was assumed that the hub driver would be its only caller. But this isn't true now; user programs can use usbfs to communicate with root hubs and get status reports. When they do this, they may use a transfer_buffer that is smaller than the data returned by the HCD, which will lead to a buffer overflow error when usb_hcd_poll_rh_status() tries to store the status data. This was discovered by syzbot: BUG: KASAN: slab-out-of-bounds in memcpy include/linux/fortify-string.h:225 [inline] BUG: KASAN: slab-out-of-bounds in usb_hcd_poll_rh_status+0x5f4/0x780 drivers/usb/core/hcd.c:776 Write of size 2 at addr ffff88801da403c0 by task syz-executor133/4062 This patch fixes the bug by reducing the amount of status data if it won't fit in the transfer_buffer. If some data gets discarded then the URB's completion status is set to -EOVERFLOW rather than 0, to let the user know what happened. Reported-and-tested-by: syzbot+3ae6a2b06f131ab9849f@syzkaller.appspotmail.com Signed-off-by: Alan Stern Cc: Link: https://lore.kernel.org/r/Yc+3UIQJ2STbxNua@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -750,6 +750,7 @@ void usb_hcd_poll_rh_status(struct usb_h { struct urb *urb; int length; + int status; unsigned long flags; char buffer[6]; /* Any root hubs with > 31 ports? */ @@ -767,11 +768,17 @@ void usb_hcd_poll_rh_status(struct usb_h if (urb) { clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags); hcd->status_urb = NULL; + if (urb->transfer_buffer_length >= length) { + status = 0; + } else { + status = -EOVERFLOW; + length = urb->transfer_buffer_length; + } urb->actual_length = length; memcpy(urb->transfer_buffer, buffer, length); usb_hcd_unlink_urb_from_ep(hcd, urb); - usb_hcd_giveback_urb(hcd, urb, 0); + usb_hcd_giveback_urb(hcd, urb, status); } else { length = 0; set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags);