aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-12-17 17:18:39 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-12-17 17:18:39 +0100
commite89b7388846e2b8aa288676365671f7ab9b7cee7 (patch)
tree3443a93a76f86a6c1ee72c489ea7ca641566e805
parentfc17aa8b63161ec92ce329edbef41ebb3490162e (diff)
downloadpatches-e89b7388846e2b8aa288676365671f7ab9b7cee7.tar.gz
usb patch
-rw-r--r--series1
-rw-r--r--usb-check-usb_get_extra_descriptor-for-proper-size.patch101
2 files changed, 102 insertions, 0 deletions
diff --git a/series b/series
index 98706032ef92a2..7cf09c80b47c70 100644
--- a/series
+++ b/series
@@ -1,5 +1,6 @@
#
+usb-check-usb_get_extra_descriptor-for-proper-size.patch
usb_DEVICE_ATTR.patch
diff --git a/usb-check-usb_get_extra_descriptor-for-proper-size.patch b/usb-check-usb_get_extra_descriptor-for-proper-size.patch
new file mode 100644
index 00000000000000..4d8d72d809a614
--- /dev/null
+++ b/usb-check-usb_get_extra_descriptor-for-proper-size.patch
@@ -0,0 +1,101 @@
+From: Mathias Payer <mathias.payer@nebelwelt.net>
+Subject: [PATCH] USB: check usb_get_extra_descriptor for proper size
+
+From: Mathias Payer <mathias.payer@nebelwelt.net>
+
+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@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c | 2 +-
+ drivers/usb/core/usb.c | 6 +++---
+ drivers/usb/host/hwa-hc.c | 2 +-
+ include/linux/usb.h | 4 ++--
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 0f9381b69a3b..d2abb754934c 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2251,7 +2251,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
+ /* descriptor may appear anywhere in config */
+ err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
+ 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))
+ return 0;
+
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 79d8bd7a612e..4ebfbd737905 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -832,14 +832,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_number);
+ */
+
+ 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,
+@@ -848,7 +848,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 684d6f074c3a..09a8ebd95588 100644
+--- a/drivers/usb/host/hwa-hc.c
++++ b/drivers/usb/host/hwa-hc.c
+@@ -640,7 +640,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 4cdd515a4385..5e49e82c4368 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -407,11 +407,11 @@ 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, \
+- type, (void **)ptr)
++ type, (void **)ptr, sizeof(**(ptr)))
+
+ /* ----------------------------------------------------------------------- */
+
+--
+2.19.2
+