Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c380600b authored by Mathias Payer's avatar Mathias Payer Committed by Greg Kroah-Hartman
Browse files

USB: check usb_get_extra_descriptor for proper size



commit 704620afc70cf47abb9d6a1a57f3825d2bca49cf 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 c19c1881
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2211,7 +2211,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;

+3 −3
Original line number Diff line number Diff line
@@ -678,14 +678,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,
@@ -694,7 +694,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;
		}
+1 −1
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -334,11 +334,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)))

/* ----------------------------------------------------------------------- */