Commit 65412e48 authored by Duncan Sands's avatar Duncan Sands Committed by Greg Kroah-Hartman

[PATCH] USB ATM: avoid oops on bind failure; plug memory leak

Zero the entire instance, not just the struct usbatm_data head.
Make sure the just allocated urb is freed if we fail to allocate
a buffer.  Based on a patch by Stanislaw W. Gruszka.
Signed-off-by: default avatarDuncan Sands <baldrick@free.fr>
Acked-by: default avatarPete Zaitcev <zaitcev@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e20d6645
...@@ -949,6 +949,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, ...@@ -949,6 +949,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_device *usb_dev = interface_to_usbdev(intf);
struct usbatm_data *instance; struct usbatm_data *instance;
char *buf; char *buf;
size_t instance_size = sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs);
int error = -ENOMEM; int error = -ENOMEM;
int i, length; int i, length;
int need_heavy; int need_heavy;
...@@ -960,14 +961,13 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, ...@@ -960,14 +961,13 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
intf->altsetting->desc.bInterfaceNumber); intf->altsetting->desc.bInterfaceNumber);
/* instance init */ /* instance init */
instance = kmalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), instance = kmalloc(instance_size, GFP_KERNEL);
GFP_KERNEL);
if (!instance) { if (!instance) {
dev_dbg(dev, "%s: no memory for instance data!\n", __func__); dev_dbg(dev, "%s: no memory for instance data!\n", __func__);
return -ENOMEM; return -ENOMEM;
} }
memset(instance, 0, sizeof(*instance)); memset(instance, 0, instance_size);
/* public fields */ /* public fields */
...@@ -1051,6 +1051,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, ...@@ -1051,6 +1051,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
goto fail_unbind; goto fail_unbind;
} }
instance->urbs[i] = urb;
buffer = kmalloc(channel->buf_size, GFP_KERNEL); buffer = kmalloc(channel->buf_size, GFP_KERNEL);
if (!buffer) { if (!buffer) {
dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i); dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i);
...@@ -1078,7 +1080,6 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, ...@@ -1078,7 +1080,6 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p", vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p",
__func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb);
instance->urbs[i] = urb;
} }
if (need_heavy && driver->heavy_init) { if (need_heavy && driver->heavy_init) {
......
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