summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Khoroshilov <khoroshilov@ispras.ru>2014-09-08 19:10:43 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-09-23 16:13:38 -0300
commite947d9ad8ab118d51ff07b7d93c3c1a3e9f7c42f (patch)
treed9a80a48ec5803301caa91cfa4abb4a9ad6e764c
parent3011e5e592a2d31556cc3eff335a1ecccd473fa0 (diff)
downloadlinux-e947d9ad8ab118d51ff07b7d93c3c1a3e9f7c42f.tar.gz
linux-e947d9ad8ab118d51ff07b7d93c3c1a3e9f7c42f.tar.bz2
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>
-rw-r--r--drivers/media/rc/mceusb.c11
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);
}