Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Duncan Sands and committed by
Greg Kroah-Hartman
65412e48 e20d6645

+5 -4
+5 -4
drivers/usb/atm/usbatm.c
··· 949 949 struct usb_device *usb_dev = interface_to_usbdev(intf); 950 950 struct usbatm_data *instance; 951 951 char *buf; 952 + size_t instance_size = sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs); 952 953 int error = -ENOMEM; 953 954 int i, length; 954 955 int need_heavy; ··· 961 960 intf->altsetting->desc.bInterfaceNumber); 962 961 963 962 /* instance init */ 964 - instance = kmalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), 965 - GFP_KERNEL); 963 + instance = kmalloc(instance_size, GFP_KERNEL); 966 964 if (!instance) { 967 965 dev_dbg(dev, "%s: no memory for instance data!\n", __func__); 968 966 return -ENOMEM; 969 967 } 970 968 971 - memset(instance, 0, sizeof(*instance)); 969 + memset(instance, 0, instance_size); 972 970 973 971 /* public fields */ 974 972 ··· 1051 1051 goto fail_unbind; 1052 1052 } 1053 1053 1054 + instance->urbs[i] = urb; 1055 + 1054 1056 buffer = kmalloc(channel->buf_size, GFP_KERNEL); 1055 1057 if (!buffer) { 1056 1058 dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i); ··· 1080 1078 1081 1079 vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p", 1082 1080 __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb); 1083 - instance->urbs[i] = urb; 1084 1081 } 1085 1082 1086 1083 if (need_heavy && driver->heavy_init) {