Commit 401abfce authored by Oleg Drokin's avatar Oleg Drokin Committed by Oleg Drokin

[PATCH] USB: Memleak in drivers/usb/hub.c::usb_reset_device

Hello!

On Fri, Mar 14, 2003 at 11:37:19AM -0800, Greg KH wrote:
> >    There seems to be a memleak in drivers/usb/hub.c::usb_reset_device()
> >    on error exit path. See the patch.
> >    Found with help of smatch + enhanced unfree script.
> And yes, as David said, there is another kind of error in this area for
> 2.5.  Patches to clean that up would be appreciated.

Ok, I guess something like that should work:
parent 1bee5616
...@@ -1175,7 +1175,7 @@ void usb_hub_cleanup(void) ...@@ -1175,7 +1175,7 @@ void usb_hub_cleanup(void)
int usb_reset_device(struct usb_device *dev) int usb_reset_device(struct usb_device *dev)
{ {
struct usb_device *parent = dev->parent; struct usb_device *parent = dev->parent;
struct usb_device_descriptor descriptor; struct usb_device_descriptor *descriptor;
int i, ret, port = -1; int i, ret, port = -1;
if (!parent) { if (!parent) {
...@@ -1224,17 +1224,24 @@ int usb_reset_device(struct usb_device *dev) ...@@ -1224,17 +1224,24 @@ int usb_reset_device(struct usb_device *dev)
* If nothing changed, we reprogram the configuration and then * If nothing changed, we reprogram the configuration and then
* the alternate settings. * the alternate settings.
*/ */
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor, descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
sizeof(descriptor)); if (!descriptor) {
if (ret < 0) return -ENOMEM;
}
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor,
sizeof(*descriptor));
if (ret < 0) {
kfree(descriptor);
return ret; return ret;
}
le16_to_cpus(&descriptor.bcdUSB); le16_to_cpus(&descriptor->bcdUSB);
le16_to_cpus(&descriptor.idVendor); le16_to_cpus(&descriptor->idVendor);
le16_to_cpus(&descriptor.idProduct); le16_to_cpus(&descriptor->idProduct);
le16_to_cpus(&descriptor.bcdDevice); le16_to_cpus(&descriptor->bcdDevice);
if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) { if (memcmp(&dev->descriptor, descriptor, sizeof(*descriptor))) {
kfree(descriptor);
usb_destroy_configuration(dev); usb_destroy_configuration(dev);
ret = usb_get_device_descriptor(dev); ret = usb_get_device_descriptor(dev);
...@@ -1268,6 +1275,8 @@ int usb_reset_device(struct usb_device *dev) ...@@ -1268,6 +1275,8 @@ int usb_reset_device(struct usb_device *dev)
return 1; return 1;
} }
kfree(descriptor);
ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue); ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue);
if (ret < 0) { if (ret < 0) {
err("failed to set dev %s active configuration (error=%d)", err("failed to set dev %s active configuration (error=%d)",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment