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

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

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: 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 2f2dde6b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;

+3 −3
Original line number Diff line number Diff line
@@ -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;
		}
+1 −1
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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)))

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