Commit 7b6e85da authored by Mathias Payer's avatar Mathias Payer Committed by Greg Kroah-Hartman

USB: check usb_get_extra_descriptor for proper size

commit 704620af upstream.

When reading an extra descriptor, we need to properly check the minimum
and maximum size allowed, to prevent from invalid data being sent by a
device.
Reported-by: default avatarHui Peng <benquike@gmail.com>
Reported-by: default avatarMathias Payer <mathias.payer@nebelwelt.net>
Co-developed-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarHui Peng <benquike@gmail.com>
Signed-off-by: default avatarMathias Payer <mathias.payer@nebelwelt.net>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 810487aa
...@@ -2231,7 +2231,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev) ...@@ -2231,7 +2231,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
/* descriptor may appear anywhere in config */ /* descriptor may appear anywhere in config */
err = __usb_get_extra_descriptor(udev->rawdescriptors[0], err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
le16_to_cpu(udev->config[0].desc.wTotalLength), le16_to_cpu(udev->config[0].desc.wTotalLength),
USB_DT_OTG, (void **) &desc); USB_DT_OTG, (void **) &desc, sizeof(*desc));
if (err || !(desc->bmAttributes & USB_OTG_HNP)) if (err || !(desc->bmAttributes & USB_OTG_HNP))
return 0; return 0;
......
...@@ -833,14 +833,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_number); ...@@ -833,14 +833,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_number);
*/ */
int __usb_get_extra_descriptor(char *buffer, unsigned size, int __usb_get_extra_descriptor(char *buffer, unsigned size,
unsigned char type, void **ptr) unsigned char type, void **ptr, size_t minsize)
{ {
struct usb_descriptor_header *header; struct usb_descriptor_header *header;
while (size >= sizeof(struct usb_descriptor_header)) { while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer; header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) { if (header->bLength < 2 || header->bLength > size) {
printk(KERN_ERR printk(KERN_ERR
"%s: bogus descriptor, type %d length %d\n", "%s: bogus descriptor, type %d length %d\n",
usbcore_name, usbcore_name,
...@@ -849,7 +849,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, ...@@ -849,7 +849,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
return -1; return -1;
} }
if (header->bDescriptorType == type) { if (header->bDescriptorType == type && header->bLength >= minsize) {
*ptr = header; *ptr = header;
return 0; return 0;
} }
......
...@@ -654,7 +654,7 @@ static int hwahc_security_create(struct hwahc *hwahc) ...@@ -654,7 +654,7 @@ static int hwahc_security_create(struct hwahc *hwahc)
top = itr + itr_size; top = itr + itr_size;
result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index], result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
le16_to_cpu(usb_dev->actconfig->desc.wTotalLength), le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
USB_DT_SECURITY, (void **) &secd); USB_DT_SECURITY, (void **) &secd, sizeof(*secd));
if (result == -1) { if (result == -1) {
dev_warn(dev, "BUG? WUSB host has no security descriptors\n"); dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
return 0; return 0;
......
...@@ -407,11 +407,11 @@ struct usb_host_bos { ...@@ -407,11 +407,11 @@ struct usb_host_bos {
}; };
int __usb_get_extra_descriptor(char *buffer, unsigned size, int __usb_get_extra_descriptor(char *buffer, unsigned size,
unsigned char type, void **ptr); unsigned char type, void **ptr, size_t min);
#define usb_get_extra_descriptor(ifpoint, type, ptr) \ #define usb_get_extra_descriptor(ifpoint, type, ptr) \
__usb_get_extra_descriptor((ifpoint)->extra, \ __usb_get_extra_descriptor((ifpoint)->extra, \
(ifpoint)->extralen, \ (ifpoint)->extralen, \
type, (void **)ptr) type, (void **)ptr, sizeof(**(ptr)))
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment