ChangeSet 1.1315.8.24, 2003/09/17 17:59:40-07:00, [EMAIL PROTECTED]
[PATCH] USB: Changes to core/config.c (5 of 9)
This patch centralizes the error checking for invalid descriptor lengths
and unexpected descriptor types. Instead of doing it in three different
places -- while parsing configuration, interface, and endpoint descriptors
-- the new code does it all at once. Not surprisingly, this yields a net
savings in code size.
drivers/usb/core/config.c | 76 ++++++++++++++++++++++------------------------
1 files changed, 37 insertions(+), 39 deletions(-)
diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c
--- a/drivers/usb/core/config.c Fri Sep 19 17:09:44 2003
+++ b/drivers/usb/core/config.c Fri Sep 19 17:09:44 2003
@@ -37,23 +37,15 @@
buffer += header->bLength;
size -= header->bLength;
- /* Skip over the rest of the Class Specific or Vendor Specific */
- /* descriptors */
+ /* Skip over any Class Specific or Vendor Specific descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
- if (header->bLength < 2) {
- err("invalid descriptor length of %d", header->bLength);
- return -EINVAL;
- }
-
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
- (header->bDescriptorType == USB_DT_INTERFACE) ||
- (header->bDescriptorType == USB_DT_CONFIG) ||
- (header->bDescriptorType == USB_DT_DEVICE))
+ (header->bDescriptorType == USB_DT_INTERFACE))
break;
dbg("skipping descriptor 0x%X", header->bDescriptorType);
@@ -155,27 +147,18 @@
memcpy(&ifp->desc, buffer, USB_DT_INTERFACE_SIZE);
- /* Skip over the interface */
buffer += ifp->desc.bLength;
size -= ifp->desc.bLength;
+ /* Skip over any Class Specific or Vendor Specific descriptors */
begin = buffer;
numskipped = 0;
-
- /* Skip over any interface, class or vendor descriptors */
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
- if (header->bLength < 2) {
- err("invalid descriptor length of %d",
header->bLength);
- return -EINVAL;
- }
-
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_INTERFACE) ||
- (header->bDescriptorType == USB_DT_ENDPOINT) ||
- (header->bDescriptorType == USB_DT_CONFIG) ||
- (header->bDescriptorType == USB_DT_DEVICE))
+ (header->bDescriptorType == USB_DT_ENDPOINT))
break;
dbg("skipping descriptor 0x%X", header->bDescriptorType);
@@ -184,7 +167,6 @@
buffer += header->bLength;
size -= header->bLength;
}
-
if (numskipped) {
dbg("skipped %d class/vendor specific interface descriptors",
numskipped);
@@ -201,13 +183,6 @@
ifp->extralen = len;
}
- /* Did we hit an unexpected descriptor? */
- header = (struct usb_descriptor_header *)buffer;
- if ((size >= sizeof(struct usb_descriptor_header)) &&
- ((header->bDescriptorType == USB_DT_CONFIG) ||
- (header->bDescriptorType == USB_DT_DEVICE)))
- break;
-
if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
warn("too many endpoints");
return -EINVAL;
@@ -249,11 +224,13 @@
int usb_parse_configuration(struct usb_host_config *config, char *buffer)
{
int nintf;
- int i, size;
+ int i, j, size;
struct usb_interface *interface;
+ char *buffer2;
+ int size2;
+ struct usb_descriptor_header *header;
int numskipped, len;
char *begin;
- struct usb_descriptor_header *header;
int retval;
memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
@@ -283,6 +260,34 @@
get_device(&interface->dev);
}
+ /* Go through the descriptors, checking their length */
+ buffer2 = buffer;
+ size2 = size;
+ j = 0;
+ while (size2 >= sizeof(struct usb_descriptor_header)) {
+ header = (struct usb_descriptor_header *) buffer2;
+ if ((header->bLength > size2) || (header->bLength < 2)) {
+ err("invalid descriptor of length %d", header->bLength);
+ return -EINVAL;
+ }
+
+ if (header->bDescriptorType == USB_DT_INTERFACE) {
+ if (header->bLength < USB_DT_INTERFACE_SIZE) {
+ warn("invalid interface descriptor");
+ return -EINVAL;
+ }
+
+ } else if ((header->bDescriptorType == USB_DT_DEVICE ||
+ header->bDescriptorType == USB_DT_CONFIG) && j) {
+ warn("unexpected descriptor type 0x%X",
header->bDescriptorType);
+ return -EINVAL;
+ }
+
+ j = 1;
+ buffer2 += header->bLength;
+ size2 -= header->bLength;
+ }
+
buffer += config->desc.bLength;
size -= config->desc.bLength;
@@ -292,16 +297,9 @@
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
- if ((header->bLength > size) || (header->bLength < 2)) {
- err("invalid descriptor length of %d", header->bLength);
- return -EINVAL;
- }
-
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
- (header->bDescriptorType == USB_DT_INTERFACE) ||
- (header->bDescriptorType == USB_DT_CONFIG) ||
- (header->bDescriptorType == USB_DT_DEVICE))
+ (header->bDescriptorType == USB_DT_INTERFACE))
break;
dbg("skipping descriptor 0x%X", header->bDescriptorType);
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel