diff options
author | Duncan Sands <duncan.sands@math.u-psud.fr> | 2005-05-27 04:00:08 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-27 17:43:58 -0400 |
commit | 65412e48e21ff4fdaf2aea1565ef4fb3ef5262ce (patch) | |
tree | 084813b21b98aed0ef97db6160663e5abff0991a /drivers/usb/atm/usbatm.c | |
parent | e20d6645f794b51835e6f740a5b6f95c7e3fd843 (diff) |
[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: Duncan Sands <baldrick@free.fr>
Acked-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/atm/usbatm.c')
-rw-r--r-- | drivers/usb/atm/usbatm.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index bb2b5d256e34..b178c800ced8 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -949,6 +949,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
949 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 949 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
950 | struct usbatm_data *instance; | 950 | struct usbatm_data *instance; |
951 | char *buf; | 951 | char *buf; |
952 | size_t instance_size = sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs); | ||
952 | int error = -ENOMEM; | 953 | int error = -ENOMEM; |
953 | int i, length; | 954 | int i, length; |
954 | int need_heavy; | 955 | int need_heavy; |
@@ -960,14 +961,13 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
960 | intf->altsetting->desc.bInterfaceNumber); | 961 | intf->altsetting->desc.bInterfaceNumber); |
961 | 962 | ||
962 | /* instance init */ | 963 | /* instance init */ |
963 | instance = kmalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), | 964 | instance = kmalloc(instance_size, GFP_KERNEL); |
964 | GFP_KERNEL); | ||
965 | if (!instance) { | 965 | if (!instance) { |
966 | dev_dbg(dev, "%s: no memory for instance data!\n", __func__); | 966 | dev_dbg(dev, "%s: no memory for instance data!\n", __func__); |
967 | return -ENOMEM; | 967 | return -ENOMEM; |
968 | } | 968 | } |
969 | 969 | ||
970 | memset(instance, 0, sizeof(*instance)); | 970 | memset(instance, 0, instance_size); |
971 | 971 | ||
972 | /* public fields */ | 972 | /* public fields */ |
973 | 973 | ||
@@ -1051,6 +1051,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, | |||
1051 | goto fail_unbind; | 1051 | goto fail_unbind; |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | instance->urbs[i] = urb; | ||
1055 | |||
1054 | buffer = kmalloc(channel->buf_size, GFP_KERNEL); | 1056 | buffer = kmalloc(channel->buf_size, GFP_KERNEL); |
1055 | if (!buffer) { | 1057 | if (!buffer) { |
1056 | dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i); | 1058 | 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 | 1080 | ||
1079 | vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p", | 1081 | vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p", |
1080 | __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); | 1082 | __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); |
1081 | instance->urbs[i] = urb; | ||
1082 | } | 1083 | } |
1083 | 1084 | ||
1084 | if (need_heavy && driver->heavy_init) { | 1085 | if (need_heavy && driver->heavy_init) { |