Skip to content

Commit 704620a

Browse files
gannimogregkh
authored andcommitted
USB: check usb_get_extra_descriptor for proper size
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: Hui Peng <benquike@gmail.com> Reported-by: Mathias Payer <mathias.payer@nebelwelt.net> Co-developed-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Hui Peng <benquike@gmail.com> Signed-off-by: Mathias Payer <mathias.payer@nebelwelt.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 2f2dde6 commit 704620a

File tree

4 files changed

+7
-7
lines changed

4 files changed

+7
-7
lines changed

drivers/usb/core/hub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2251,7 +2251,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
22512251
/* descriptor may appear anywhere in config */
22522252
err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
22532253
le16_to_cpu(udev->config[0].desc.wTotalLength),
2254-
USB_DT_OTG, (void **) &desc);
2254+
USB_DT_OTG, (void **) &desc, sizeof(*desc));
22552255
if (err || !(desc->bmAttributes & USB_OTG_HNP))
22562256
return 0;
22572257

drivers/usb/core/usb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -832,14 +832,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_number);
832832
*/
833833

834834
int __usb_get_extra_descriptor(char *buffer, unsigned size,
835-
unsigned char type, void **ptr)
835+
unsigned char type, void **ptr, size_t minsize)
836836
{
837837
struct usb_descriptor_header *header;
838838

839839
while (size >= sizeof(struct usb_descriptor_header)) {
840840
header = (struct usb_descriptor_header *)buffer;
841841

842-
if (header->bLength < 2) {
842+
if (header->bLength < 2 || header->bLength > size) {
843843
printk(KERN_ERR
844844
"%s: bogus descriptor, type %d length %d\n",
845845
usbcore_name,
@@ -848,7 +848,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
848848
return -1;
849849
}
850850

851-
if (header->bDescriptorType == type) {
851+
if (header->bDescriptorType == type && header->bLength >= minsize) {
852852
*ptr = header;
853853
return 0;
854854
}

drivers/usb/host/hwa-hc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ static int hwahc_security_create(struct hwahc *hwahc)
640640
top = itr + itr_size;
641641
result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
642642
le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
643-
USB_DT_SECURITY, (void **) &secd);
643+
USB_DT_SECURITY, (void **) &secd, sizeof(*secd));
644644
if (result == -1) {
645645
dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
646646
return 0;

include/linux/usb.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,11 @@ struct usb_host_bos {
407407
};
408408

409409
int __usb_get_extra_descriptor(char *buffer, unsigned size,
410-
unsigned char type, void **ptr);
410+
unsigned char type, void **ptr, size_t min);
411411
#define usb_get_extra_descriptor(ifpoint, type, ptr) \
412412
__usb_get_extra_descriptor((ifpoint)->extra, \
413413
(ifpoint)->extralen, \
414-
type, (void **)ptr)
414+
type, (void **)ptr, sizeof(**(ptr)))
415415

416416
/* ----------------------------------------------------------------------- */
417417

0 commit comments

Comments
 (0)