Patch "USB: validate wMaxPacketValue entries in endpoint descriptors" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
USB: validate wMaxPacketValue entries in endpoint descriptors
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
aed9d65ac3278d4febd8665bd7db59ef53e825feMon Sep 17 00:00:00 2001
From: Alan Stern <[email protected]>
Date: Mon, 1 Aug 2016 15:25:56 -0400
Subject: USB: validate wMaxPacketValue entries in endpoint descriptors
From: Alan Stern <[email protected]>
commit aed9d65ac3278d4febd8665bd7db59ef53e825fe upstream.
Erroneous or malicious endpoint descriptors may have non-zero bits in reserved positions, or out-of-bounds values. This patch helps prevent these from causing problems by bounds-checking the wMaxPacketValue entries in endpoint descriptors and capping the values at the maximum allowed.
This issue was first discovered and tests were conducted by Jake Lamberson <[email protected]>, an intern working for Rosie Hall.
--- drivers/usb/core/config.c | 66 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-)
drivers/usb/core/config.c +63 -3
@@ -171,6 +171,31 @@ static void usb_parse_ss_endpoint_compan ep, buffer, size); } +static const unsigned short low_speed_maxpacket_maxes[4 ] = { + [USB_ENDPOINT_XFER_CONTROL ] =8 , + [USB_ENDPOINT_XFER_ISOC ] =0 , + [USB_ENDPOINT_XFER_BULK ] =0 , + [USB_ENDPOINT_XFER_INT ] =8 , +}; +static const unsigned short full_speed_maxpacket_maxes[4 ] = { + [USB_ENDPOINT_XFER_CONTROL ] =64 , + [USB_ENDPOINT_XFER_ISOC ] =1023 , + [USB_ENDPOINT_XFER_BULK ] =64 , + [USB_ENDPOINT_XFER_INT ] =64 , +}; +static const unsigned short high_speed_maxpacket_maxes[4 ] = { + [USB_ENDPOINT_XFER_CONTROL ] =64 , + [USB_ENDPOINT_XFER_ISOC ] =1024 , + [USB_ENDPOINT_XFER_BULK ] =512 , + [USB_ENDPOINT_XFER_INT ] =1023 , +}; +static const unsigned short super_speed_maxpacket_maxes[4 ] = { + [USB_ENDPOINT_XFER_CONTROL ] =512 , + [USB_ENDPOINT_XFER_ISOC ] =1024 , + [USB_ENDPOINT_XFER_BULK ] =1024 , + [USB_ENDPOINT_XFER_INT ] =1024 , +}; +static int usb_parse_endpoint (struct device *ddev,int cfgno,int inum,int asnum,struct usb_host_interface *ifp,int num_ep,unsigned char *buffer,int size)
@@ -179,6 +204,8 @@ static int usb_parse_endpoint(struct devstruct usb_endpoint_descriptor *d;struct usb_host_endpoint *endpoint;int n, i, j, retval; +unsigned int maxp; +const unsigned short *maxpacket_maxes; d = (struct usb_endpoint_descriptor *) buffer; buffer += d->bLength;
@@ -286,6 +313,42 @@ static int usb_parse_endpoint(struct dev endpoint->desc.wMaxPacketSize =cpu_to_le16 (8 ); } +/* Validate the wMaxPacketSize field */ + maxp =usb_endpoint_maxp (&endpoint->desc); + +/* Find the highest legal maxpacket size for this endpoint */ + i =0 ;/* additional transactions per microframe */ +switch (to_usb_device (ddev)->speed) { +case USB_SPEED_LOW : + maxpacket_maxes = low_speed_maxpacket_maxes; +break ; +case USB_SPEED_FULL : + maxpacket_maxes = full_speed_maxpacket_maxes; +break ; +case USB_SPEED_HIGH : +/* Bits 12..11 are allowed only for HS periodic endpoints */ +if (usb_endpoint_xfer_int (d) ||usb_endpoint_xfer_isoc (d)) { + i = maxp & (BIT (12 ) |BIT (11 )); + maxp &= ~i; + } +/* fallthrough */ +default : + maxpacket_maxes = high_speed_maxpacket_maxes; +break ; +case USB_SPEED_SUPER : +case USB_SPEED_SUPER_PLUS : + maxpacket_maxes = super_speed_maxpacket_maxes; +break ; + } + j = maxpacket_maxes[usb_endpoint_type (&endpoint->desc)]; + +if (maxp > j) { +dev_warn (ddev,"config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n" , + cfgno, inum, asnum, d->bEndpointAddress, maxp, j); + maxp = j; + endpoint->desc.wMaxPacketSize =cpu_to_le16 (i | maxp); + } +/* * Some buggy high speed devices have bulk endpoints using * maxpacket sizes other than 512. High speed HCDs may not
@@ -293,9 +356,6 @@ static int usb_parse_endpoint(struct dev*/ if (to_usb_device (ddev)->speed ==USB_SPEED_HIGH &&usb_endpoint_xfer_bulk (d)) { -unsigned maxp; - - maxp =usb_endpoint_maxp (&endpoint->desc) &0x07ff ;if (maxp !=512 ) dev_warn(ddev, "config %d interface %d altsetting %d " "bulk endpoint 0x%X has invalid maxpacket %d\n",
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/usb-ehci-change-order-of-register-cleanup-during-shutdown.patch queue-4.7/usb-devio-do-not-warn-when-allocation-fails.patch queue-4.7/usb-hub-fix-up-early-exit-pathway-in-hub_activate.patch queue-4.7/usb-hub-change-the-locking-in-hub_activate.patch queue-4.7/usb-validate-wmaxpacketvalue-entries-in-endpoint-descriptors.patch queue-4.7/usb-serial-fix-memleak-in-driver-registration-error-path.patch queue-4.7/usb-hub-fix-unbalanced-reference-count-memory-leak-deadlocks.patch queue-4.7/usb-misc-usbtest-add-fix-for-driver-hang.patch