Patch "USB: core: Add type-specific length check of BOS descriptors" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
USB: core: Add type-specific length check of BOS descriptors
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-core-add-type-specific-length-check-of-bos-descriptors.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
81cf4a45360f70528f1f64ba018d61cb5767249aMon Sep 17 00:00:00 2001
From: Masakazu Mokuno <[email protected]>
Date: Fri, 10 Nov 2017 01:25:50 +0900
Subject: USB: core: Add type-specific length check of BOS descriptors
From: Masakazu Mokuno <[email protected]>
commit 81cf4a45360f70528f1f64ba018d61cb5767249a upstream.
As most of BOS descriptors are longer in length than their header 'struct usb_dev_cap_header', comparing solely with it is not sufficient to avoid out-of-bounds access to BOS descriptors.
This patch adds descriptor type specific length check in usb_get_bos_descriptor() to fix the issue.
--- drivers/usb/core/config.c | 28 ++++++++++++++++++++++++---- include/uapi/linux/usb/ch9.h | 3 +++ 2 files changed, 27 insertions(+), 4 deletions(-)
drivers/usb/core/config.c +24 -4
@@ -871,14 +871,25 @@ void usb_release_bos_descriptor(struct u } } +static const __u8 bos_desc_len[256 ] = { + [USB_CAP_TYPE_WIRELESS_USB ] =USB_DT_USB_WIRELESS_CAP_SIZE , + [USB_CAP_TYPE_EXT ] =USB_DT_USB_EXT_CAP_SIZE , + [USB_SS_CAP_TYPE ] =USB_DT_USB_SS_CAP_SIZE , + [USB_SSP_CAP_TYPE ] =USB_DT_USB_SSP_CAP_SIZE (1 ), + [CONTAINER_ID_TYPE ] =USB_DT_USB_SS_CONTN_ID_SIZE , + [USB_PTM_CAP_TYPE ] =USB_DT_USB_PTM_ID_SIZE , +}; +/* Get BOS descriptor set */ int usb_get_bos_descriptor (struct usb_device *dev) {struct device *ddev = &dev->dev;struct usb_bos_descriptor *bos;struct usb_dev_cap_header *cap; +struct usb_ssp_cap_descriptor *ssp_cap;unsigned char *buffer; -int length, total_len, num, i; +int length, total_len, num, i, ssac; +__u8 cap_type;int ret; bos =kzalloc (sizeof (struct usb_bos_descriptor ),GFP_KERNEL );
@@ -931,7 +942,13 @@ int usb_get_bos_descriptor(struct usb_de dev->bos->desc->bNumDeviceCaps = i;break ; } + cap_type = cap->bDevCapabilityType; length = cap->bLength; +if (bos_desc_len[cap_type] && length < bos_desc_len[cap_type]) { + dev->bos->desc->bNumDeviceCaps = i; +break ; + } + total_len -= length;if (cap->bDescriptorType !=USB_DT_DEVICE_CAPABILITY ) {
@@ -939,7 +956,7 @@ int usb_get_bos_descriptor(struct usb_decontinue ; } -switch (cap->bDevCapabilityType) { +switch (cap_type) {case USB_CAP_TYPE_WIRELESS_USB :/* Wireless USB cap descriptor is handled by wusb */ break ;
@@ -952,8 +969,11 @@ int usb_get_bos_descriptor(struct usb_de (struct usb_ss_cap_descriptor *)buffer;break ;case USB_SSP_CAP_TYPE : - dev->bos->ssp_cap = - (struct usb_ssp_cap_descriptor *)buffer; + ssp_cap = (struct usb_ssp_cap_descriptor *)buffer; + ssac = (le32_to_cpu (ssp_cap->bmAttributes) & +USB_SSP_SUBLINK_SPEED_ATTRIBS ) +1 ; +if (length >=USB_DT_USB_SSP_CAP_SIZE (ssac)) + dev->bos->ssp_cap = ssp_cap;break ;case CONTAINER_ID_TYPE : dev->bos->ss_id =
include/uapi/linux/usb/ch9.h +3 -0
@@ -812,6 +812,8 @@ struct usb_wireless_cap_descriptor { /*__u8 bReserved; } __attribute__((packed)); +#define USB_DT_USB_WIRELESS_CAP_SIZE 11 +/* USB 2.0 Extension descriptor */ #define USB_CAP_TYPE_EXT 2
@@ -991,6 +993,7 @@ enum usb3_link_state { USB3_LPM_U3 }; +#define USB_DT_USB_PTM_ID_SIZE 3/* * A U1 timeout of 0x0 means the parent hub will reject any transitions to U1. * 0xff means the parent hub will accept transitions to U1, but will not
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/usb-core-add-type-specific-length-check-of-bos-descriptors.patch