From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sn1nam01on0099.outbound.protection.outlook.com ([104.47.32.99]:2346 "EHLO NAM01-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752062AbeARVF2 (ORCPT ); Thu, 18 Jan 2018 16:05:28 -0500 From: Sasha Levin To: "stable@vger.kernel.org" , "stable-commits@vger.kernel.org" CC: Alan Stern , Greg Kroah-Hartman , Sasha Levin Subject: [added to the 4.1 stable tree] USB: core: prevent malicious bNumInterfaces overflow Date: Thu, 18 Jan 2018 21:01:18 +0000 Message-ID: <20180118205908.3220-214-alexander.levin@microsoft.com> References: <20180118205908.3220-1-alexander.levin@microsoft.com> In-Reply-To: <20180118205908.3220-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Alan Stern This patch has been added to the stable tree. If you have any objections, please let us know. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [ Upstream commit 48a4ff1c7bb5a32d2e396b03132d20d552c0eca7 ] A malicious USB device with crafted descriptors can cause the kernel to access unallocated memory by setting the bNumInterfaces value too high in a configuration descriptor. Although the value is adjusted during parsing, this adjustment is skipped in one of the error return paths. This patch prevents the problem by setting bNumInterfaces to 0 initially. The existing code already sets it to the proper value after parsing is complete. Signed-off-by: Alan Stern Reported-by: Andrey Konovalov CC: Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/core/config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 0b99f913d7f2..b868e77f3bfb 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -460,6 +460,9 @@ static int usb_parse_configuration(struct usb_device *d= ev, int cfgidx, unsigned iad_num =3D 0; =20 memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); + nintf =3D nintf_orig =3D config->desc.bNumInterfaces; + config->desc.bNumInterfaces =3D 0; // Adjusted later + if (config->desc.bDescriptorType !=3D USB_DT_CONFIG || config->desc.bLength < USB_DT_CONFIG_SIZE || config->desc.bLength > size) { @@ -473,7 +476,6 @@ static int usb_parse_configuration(struct usb_device *d= ev, int cfgidx, buffer +=3D config->desc.bLength; size -=3D config->desc.bLength; =20 - nintf =3D nintf_orig =3D config->desc.bNumInterfaces; if (nintf > USB_MAXINTERFACES) { dev_warn(ddev, "config %d has too many interfaces: %d, " "using maximum allowed: %d\n", --=20 2.11.0