Subject: USB ATM: avoid oops on bind failure; plug memory leak

From: Duncan Sands <[email-masked]>
Date: Fri, 27 May 2005 10:00:08 +0200

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: Duncan Sands <[email-masked]>
Acked-by: Pete Zaitcev <[email-masked]>
Signed-off-by: Greg Kroah-Hartman <[email-masked]>

---
 drivers/usb/atm/usbatm.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

--- gregkh-2.6.orig/drivers/usb/atm/usbatm.c	2005-05-27 21:00:43.000000000 -0700
+++ gregkh-2.6/drivers/usb/atm/usbatm.c	2005-05-27 21:00:52.000000000 -0700
@@ -949,6 +949,7 @@
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	struct usbatm_data *instance;
 	char *buf;
+	size_t instance_size = sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs);
 	int error = -ENOMEM;
 	int i, length;
 	int need_heavy;
@@ -960,14 +961,13 @@
 			intf->altsetting->desc.bInterfaceNumber);
 
 	/* instance init */
-	instance = kmalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs),
-			   GFP_KERNEL);
+	instance = kmalloc(instance_size, GFP_KERNEL);
 	if (!instance) {
 		dev_dbg(dev, "%s: no memory for instance data!\n", __func__);
 		return -ENOMEM;
 	}
 
-	memset(instance, 0, sizeof(*instance));
+	memset(instance, 0, instance_size);
 
 	/* public fields */
 
@@ -1051,6 +1051,8 @@
 			goto fail_unbind;
 		}
 
+		instance->urbs[i] = urb;
+
 		buffer = kmalloc(channel->buf_size, GFP_KERNEL);
 		if (!buffer) {
 			dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i);
@@ -1078,7 +1080,6 @@
 
 		vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p",
 		     __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb);
-		instance->urbs[i] = urb;
 	}
 
 	if (need_heavy && driver->heavy_init) {