mirror of
https://bitbucket.org/padavan/rt-n56u.git
synced 2025-12-19 03:34:56 +08:00
USB: core: Add type-specific length check of BOS descriptors
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. Signed-off-by: Masakazu Mokuno <masakazu.mokuno@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> [bwh: Backported to 3.2: - Drop handling of USB_PTM_CAP_TYPE and USB_SSP_CAP_TYPE - Adjust filename] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
This commit is contained in:
committed by
andy.padavan
parent
ab9fb9c293
commit
79720c54b2
@@ -786,6 +786,13 @@ void usb_release_bos_descriptor(struct usb_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
[CONTAINER_ID_TYPE] = USB_DT_USB_SS_CONTN_ID_SIZE,
|
||||
};
|
||||
|
||||
/* Get BOS descriptor set */
|
||||
int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
{
|
||||
@@ -794,6 +801,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
struct usb_dev_cap_header *cap;
|
||||
unsigned char *buffer;
|
||||
int length, total_len, num, i;
|
||||
__u8 cap_type;
|
||||
int ret;
|
||||
|
||||
bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL);
|
||||
@@ -846,7 +854,13 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
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) {
|
||||
@@ -854,7 +868,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (cap->bDevCapabilityType) {
|
||||
switch (cap_type) {
|
||||
case USB_CAP_TYPE_WIRELESS_USB:
|
||||
/* Wireless USB cap descriptor is handled by wusb */
|
||||
break;
|
||||
|
||||
@@ -787,6 +787,8 @@ struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
|
||||
__u8 bReserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define USB_DT_USB_WIRELESS_CAP_SIZE 11
|
||||
|
||||
/* USB 2.0 Extension descriptor */
|
||||
#define USB_CAP_TYPE_EXT 2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user