summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuangshuo Li <lgs201920130244@gmail.com>2026-07-14 23:16:48 +0800
committerHans Verkuil <hverkuil+cisco@kernel.org>2026-07-28 15:17:54 +0200
commitbbd4218310cc9fc8bba677e8c35abd03524ad474 (patch)
treef06f7511c2b7452fdbcb9464244773e92623812d
parent0735e0b5a96761a9ce277a238e834008ad92a0a5 (diff)
downloadlinux-next-bbd4218310cc9fc8bba677e8c35abd03524ad474.tar.gz
linux-next-bbd4218310cc9fc8bba677e8c35abd03524ad474.zip
media: usbtv: Fix V4L2 refcount leak on probe failure
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 <lgs201920130244@gmail.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
-rw-r--r--drivers/media/usb/usbtv/usbtv-core.c5
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c4
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);