ChangeSet 1.1315.8.21, 2003/09/17 17:08:46-07:00, [EMAIL PROTECTED]
[PATCH] USB: Changes to core/config.c (2 of 9)
This patch fixes the most blatant problems that can happen when an error
is encountered during descriptor parsing.
The struct device embedded within a struct usb_interface is
initialized as soon as the structure is allocated, so that when
put_device() is called it will contain valid data.
put_device() is not called for unallocated interfaces.
The pointers in config->extra are freed when the struct
usb_host_config is freed.
rawdescriptor pointers are initialized to 0 so that they can be
freed without error.
Partially parsed configurations are remembered so that they will
be deallocated when the entire struct usb_device is freed.
drivers/usb/core/config.c | 41 +++++++++++++++++++----------------------
1 files changed, 19 insertions(+), 22 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:10:34 2003
+++ b/drivers/usb/core/config.c Fri Sep 19 17:10:34 2003
@@ -134,12 +134,6 @@
interface->act_altsetting = 0;
interface->num_altsetting = 0;
interface->max_altsetting = USB_ALTSETTINGALLOC;
- device_initialize(&interface->dev);
- interface->dev.release = usb_release_intf;
-
- /* put happens in usb_destroy_configuration */
- get_device(&interface->dev);
-
interface->altsetting = kmalloc(sizeof(*interface->altsetting) *
interface->max_altsetting,
GFP_KERNEL);
@@ -284,6 +278,7 @@
int usb_parse_configuration(struct usb_host_config *config, char *buffer)
{
int i, size;
+ struct usb_interface *interface;
int retval = -EINVAL;
struct usb_descriptor_header *header;
@@ -296,18 +291,23 @@
if (config->desc.bNumInterfaces > USB_MAXINTERFACES) {
warn("too many interfaces");
- goto error;
+ return -EINVAL;
}
for (i = 0; i < config->desc.bNumInterfaces; ++i) {
- config->interface[i] = kmalloc(sizeof(struct usb_interface),
GFP_KERNEL);
- dbg("kmalloc IF %p, numif %i", config->interface[i], i);
- if (!config->interface[i]) {
+ interface = config->interface[i] =
+ kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
+ dbg("kmalloc IF %p, numif %i", interface, i);
+ if (!interface) {
err("out of memory");
- retval = -ENOMEM;
- goto error;
+ return -ENOMEM;
}
- memset(config->interface[i], 0x00, sizeof(struct usb_interface));
+ memset(interface, 0, sizeof(struct usb_interface));
+ interface->dev.release = usb_release_intf;
+ device_initialize(&interface->dev);
+
+ /* put happens in usb_destroy_configuration */
+ get_device(&interface->dev);
}
buffer += config->desc.bLength;
@@ -376,10 +376,6 @@
}
return size;
-error:
- for (i = 0; i < USB_MAXINTERFACES; ++i)
- kfree(config->interface[i]);
- return retval;
}
// hub-only!! ... and only exported for reset/reinit path.
@@ -401,13 +397,13 @@
for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
struct usb_host_config *cf = &dev->config[c];
- if (!cf->interface)
- break;
-
for (i = 0; i < cf->desc.bNumInterfaces; i++) {
struct usb_interface *ifp = cf->interface[i];
- put_device(&ifp->dev);
+
+ if (ifp)
+ put_device(&ifp->dev);
}
+ kfree(cf->extra);
}
kfree(dev->config);
}
@@ -449,6 +445,7 @@
err("out of memory");
return -ENOMEM;
}
+ memset(dev->rawdescriptors, 0, sizeof(char *) *
dev->descriptor.bNumConfigurations);
buffer = kmalloc(8, GFP_KERNEL);
if (!buffer) {
@@ -502,7 +499,7 @@
if (result > 0)
dbg("descriptor data left");
else if (result < 0) {
- result = -EINVAL;
+ ++cfgno;
goto err;
}
}
-------------------------------------------------------
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