diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2014-09-09 00:10:43 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-09-23 21:13:38 +0200 |
commit | e947d9ad8ab118d51ff07b7d93c3c1a3e9f7c42f (patch) | |
tree | d9a80a48ec5803301caa91cfa4abb4a9ad6e764c /drivers/media/rc/mceusb.c | |
parent | [media] firewire: firedtv-avc: potential buffer overflow (diff) | |
download | linux-e947d9ad8ab118d51ff07b7d93c3c1a3e9f7c42f.tar.xz linux-e947d9ad8ab118d51ff07b7d93c3c1a3e9f7c42f.zip |
[media] mceusb: fix usbdev leak
mceusb_init_rc_dev() does usb_get_dev(), but there is no any
usb_put_dev() in the driver.
The patch tries to straighten logic. It moves usb_get_dev()
directly to mceusb_dev_probe() and adds usb_put_dev() to an error path
and to mceusb_dev_disconnect().
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/rc/mceusb.c')
-rw-r--r-- | drivers/media/rc/mceusb.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 383e24af91ec..2cdb740cde48 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1202,10 +1202,9 @@ static void mceusb_flash_led(struct mceusb_dev *ir) mce_async_out(ir, FLASH_LED, sizeof(FLASH_LED)); } -static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir, - struct usb_interface *intf) +static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) { - struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf)); + struct usb_device *udev = ir->usbdev; struct device *dev = ir->dev; struct rc_dev *rc; int ret; @@ -1345,7 +1344,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, if (!ir->urb_in) goto urb_in_alloc_fail; - ir->usbdev = dev; + ir->usbdev = usb_get_dev(dev); ir->dev = &intf->dev; ir->len_in = maxp; ir->flags.microsoft_gen1 = is_microsoft_gen1; @@ -1366,7 +1365,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, snprintf(name + strlen(name), sizeof(name) - strlen(name), " %s", buf); - ir->rc = mceusb_init_rc_dev(ir, intf); + ir->rc = mceusb_init_rc_dev(ir); if (!ir->rc) goto rc_dev_fail; @@ -1412,6 +1411,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, /* Error-handling path */ rc_dev_fail: + usb_put_dev(ir->usbdev); usb_free_urb(ir->urb_in); urb_in_alloc_fail: usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); @@ -1439,6 +1439,7 @@ static void mceusb_dev_disconnect(struct usb_interface *intf) usb_kill_urb(ir->urb_in); usb_free_urb(ir->urb_in); usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); + usb_put_dev(dev); kfree(ir); } |