From 6a8a2cb2074c7cea49663c2399e721222d689b7f Mon Sep 17 00:00:00 2001 From: npt-1707 Date: Tue, 17 Mar 2026 03:49:40 +0800 Subject: [PATCH] drivers/usb: check usb_get_extra_descriptor for proper size --- drivers/usb/core/hub.c | 2 +- drivers/usb/core/usb.c | 6 +++--- drivers/usb/host/hwa-hc.c | 2 +- include/linux/usb.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5e2ea59976..1f66b77adb 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2270,7 +2270,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev) /* descriptor may appear anywhere in config */ if (__usb_get_extra_descriptor (udev->rawdescriptors[0], le16_to_cpu(udev->config[0].desc.wTotalLength), - USB_DT_OTG, (void **) &desc) == 0) { + USB_DT_OTG, (void **) &desc, sizeof(*desc)); if (desc->bmAttributes & USB_OTG_HNP) { unsigned port1 = udev->portnum; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index aae67e0e94..fce7b0c16a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -710,14 +710,14 @@ EXPORT_SYMBOL(usb_get_xfer_ring_dma_addr); */ 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; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; - if (header->bLength < 2) { + if (header->bLength < 2 || header->bLength > size) { printk(KERN_ERR "%s: bogus descriptor, type %d length %d\n", usbcore_name, @@ -726,7 +726,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, return -1; } - if (header->bDescriptorType == type) { + if (header->bDescriptorType == type && header->bLength >= minsize) { *ptr = header; return 0; } diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 1db0626c8b..97750f162f 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -654,7 +654,7 @@ static int hwahc_security_create(struct hwahc *hwahc) top = itr + itr_size; result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index], le16_to_cpu(usb_dev->actconfig->desc.wTotalLength), - USB_DT_SECURITY, (void **) &secd); + USB_DT_SECURITY, (void **) &secd, sizeof(*secd)); if (result == -1) { dev_warn(dev, "BUG? WUSB host has no security descriptors\n"); return 0; diff --git a/include/linux/usb.h b/include/linux/usb.h index 0f4f50926f..0e7530bb8a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -329,7 +329,7 @@ struct usb_host_bos { }; 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) \ __usb_get_extra_descriptor((ifpoint)->extra, \ (ifpoint)->extralen, \