diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2015-03-27 19:39:09 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-02 23:55:20 -0300 |
commit | afd270d1a45043cef14341bcceff62ed50e8dc9a (patch) | |
tree | 1d4eb5414cdb217841453d083d4c48f45fd136d8 /drivers/media/usb | |
parent | cc7d2dfb75b3ac0f248801ceed65f69465eb0389 (diff) | |
download | lwn-afd270d1a45043cef14341bcceff62ed50e8dc9a.tar.gz lwn-afd270d1a45043cef14341bcceff62ed50e8dc9a.zip |
[media] usbvision: fix leak of usb_dev on failure paths in usbvision_probe()
There is no usb_put_dev() on failure paths in usbvision_probe().
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/usbvision/usbvision-video.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 2579c874b83b..12b403e78d52 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1507,7 +1507,7 @@ static int usbvision_probe(struct usb_interface *intf, const struct usb_host_interface *interface; struct usb_usbvision *usbvision = NULL; const struct usb_endpoint_descriptor *endpoint; - int model, i; + int model, i, ret; PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", dev->descriptor.idVendor, @@ -1516,7 +1516,8 @@ static int usbvision_probe(struct usb_interface *intf, model = devid->driver_info; if (model < 0 || model >= usbvision_device_data_size) { PDEBUG(DBG_PROBE, "model out of bounds %d", model); - return -ENODEV; + ret = -ENODEV; + goto err_usb; } printk(KERN_INFO "%s: %s found\n", __func__, usbvision_device_data[model].model_string); @@ -1531,18 +1532,21 @@ static int usbvision_probe(struct usb_interface *intf, __func__, ifnum); dev_err(&intf->dev, "%s: Endpoint attributes %d", __func__, endpoint->bmAttributes); - return -ENODEV; + ret = -ENODEV; + goto err_usb; } if (usb_endpoint_dir_out(endpoint)) { dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n", __func__, ifnum); - return -ENODEV; + ret = -ENODEV; + goto err_usb; } usbvision = usbvision_alloc(dev, intf); if (usbvision == NULL) { dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto err_usb; } if (dev->descriptor.bNumConfigurations > 1) @@ -1561,8 +1565,8 @@ static int usbvision_probe(struct usb_interface *intf, usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); if (usbvision->alt_max_pkt_size == NULL) { dev_err(&intf->dev, "usbvision: out of memory!\n"); - usbvision_release(usbvision); - return -ENOMEM; + ret = -ENOMEM; + goto err_pkt; } for (i = 0; i < usbvision->num_alt; i++) { @@ -1597,6 +1601,12 @@ static int usbvision_probe(struct usb_interface *intf, PDEBUG(DBG_PROBE, "success"); return 0; + +err_pkt: + usbvision_release(usbvision); +err_usb: + usb_put_dev(dev); + return ret; } |