On Tue Jul 14 23:16:48 2026 +0800, Guangshuo Li wrote:
> usbtv_probe() allocates usbtv before usbtv_video_init() registers its
> embedded v4l2_device. v4l2_device_register() initializes the reference
> count to one, with usbtv_release() providing the final cleanup.
> 
> If video_register_device() fails, usbtv_video_init() unregisters the
> V4L2 device and returns an error without dropping the initial
> v4l2_device reference. The probe error path then calls kfree() on usbtv
> directly, leaving the reference stranded and bypassing
> usbtv_release().
> 
> Leave the initialized V4L2 device intact on this failure path. After
> releasing the USB reference, call v4l2_device_put() so the final
> reference invokes usbtv_release(). Retain the direct kfree() path for
> failures that occur before v4l2_device_register().
> 
> This issue was found by a static analysis tool I am developing.
> 
> Signed-off-by: Guangshuo Li <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/usb/usbtv/usbtv-core.c  | 5 ++++-
 drivers/media/usb/usbtv/usbtv-video.c | 4 +---
 2 files changed, 5 insertions(+), 4 deletions(-)

---

diff --git a/drivers/media/usb/usbtv/usbtv-core.c 
b/drivers/media/usb/usbtv/usbtv-core.c
index 6c4facf4f41a..4f10f6613bc4 100644
--- a/drivers/media/usb/usbtv/usbtv-core.c
+++ b/drivers/media/usb/usbtv/usbtv-core.c
@@ -119,7 +119,10 @@ usbtv_audio_fail:
 
 usbtv_video_fail:
        usb_set_intfdata(intf, NULL);
-       kfree(usbtv);
+       if (usbtv->v4l2_dev.dev)
+               v4l2_device_put(&usbtv->v4l2_dev);
+       else
+               kfree(usbtv);
 
        return ret;
 }
diff --git a/drivers/media/usb/usbtv/usbtv-video.c 
b/drivers/media/usb/usbtv/usbtv-video.c
index de0328100a60..92bc7a2509c3 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -949,13 +949,11 @@ int usbtv_video_init(struct usbtv *usbtv)
        ret = video_register_device(&usbtv->vdev, VFL_TYPE_VIDEO, -1);
        if (ret < 0) {
                dev_warn(usbtv->dev, "Could not register video device\n");
-               goto vdev_fail;
+               return ret;
        }
 
        return 0;
 
-vdev_fail:
-       v4l2_device_unregister(&usbtv->v4l2_dev);
 v4l2_fail:
 ctrl_fail:
        v4l2_ctrl_handler_free(&usbtv->ctrl);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to