[PATCH] media: as102: fix memory leak on probe failure

Guangshuo Li posted 1 patch 6 days, 17 hours ago
drivers/media/usb/as102/as102_usb_drv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] media: as102: fix memory leak on probe failure
Posted by Guangshuo Li 6 days, 17 hours ago
as102_usb_probe() initializes as102_dev->kref and takes a
usb_device reference before calling usb_register_dev().

A recent change stopped falling through from failed_stream to failed
after usb_register_dev() succeeds, so that as102_dev is not freed while
it can still be referenced by an already opened file. However, the new
error path deregisters the USB minor and returns without dropping the
probe's initial reference.

When stream buffer allocation or DVB registration fails after
usb_register_dev() succeeds, the initial reference remains held forever.
If userspace opens the device in the short window before the failure
path runs, close() only drops the open reference and the initial
reference still remains. As a result, as102_dev and the usb_device
reference held by it are leaked.

Drop the initial reference with kref_put() after usb_deregister_dev().
Also use the same kref release path for the usb_register_dev() failure
case instead of open-coding usb_put_dev() and kfree().

Fixes: 8bd29dbe03fc ("media: as102: fix to not free memory after the device is registered in as102_usb_probe()")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
 drivers/media/usb/as102/as102_usb_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c
index a11024451ceb..dfe5a6b3f97b 100644
--- a/drivers/media/usb/as102/as102_usb_drv.c
+++ b/drivers/media/usb/as102/as102_usb_drv.c
@@ -405,11 +405,11 @@ static int as102_usb_probe(struct usb_interface *intf,
 failed_stream:
 	usb_set_intfdata(intf, NULL);
 	usb_deregister_dev(intf, &as102_usb_class_driver);
+	kref_put(&as102_dev->kref, as102_usb_release);
 	return ret;
 failed:
-	usb_put_dev(as102_dev->bus_adap.usb_dev);
 	usb_set_intfdata(intf, NULL);
-	kfree(as102_dev);
+	kref_put(&as102_dev->kref, as102_usb_release);
 	return ret;
 }
 
-- 
2.43.0