On Tue Sep 15 19:25:10 2026 +0800, Guangshuo Li wrote:
> atmel_isi_probe() allocates the video device before registering the
> V4L2 async notifier. The video device is registered later from the
> notifier complete callback once the remote subdevice has been bound.
> 
> The remove path relies on the notifier unbind callback to unregister
> the video device. However, if the remote subdevice is never bound, or
> the complete callback fails before video_register_device() succeeds,
> the video device remains unregistered. In that case the unbind path
> does not release the object allocated by video_device_alloc(), and the
> remove path leaks it.
> 
> Only unregister the video device from the unbind callback when it has
> actually been registered, and clear the driver pointer afterwards.
> After unregistering and cleaning up the notifier, release the video
> device directly if the pointer is still present. This covers devices
> that were allocated but never registered while avoiding a second
> release of successfully registered devices.
> 
> This issue was found by manual code inspection.
> 
> Fixes: d12c9088c0b2a ("[media] atmel-isi: remove dependency of the soc-camera 
> framework")
> Cc: [email protected]
> Signed-off-by: Guangshuo Li <[email protected]>
> Reviewed-by: Eugen Hristev <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>

Patch committed.

Thanks,
Sakari Ailus

 drivers/media/platform/atmel/atmel-isi.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/platform/atmel/atmel-isi.c 
b/drivers/media/platform/atmel/atmel-isi.c
index f5e85271a275..fa33d11f736f 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1121,10 +1121,13 @@ static void isi_graph_notify_unbind(struct 
v4l2_async_notifier *notifier,
 {
        struct atmel_isi *isi = notifier_to_isi(notifier);
 
+       if (!video_is_registered(isi->vdev))
+               return;
+
        dev_dbg(isi->dev, "Removing %s\n", video_device_node_name(isi->vdev));
 
-       /* Checks internally if vdev have been init or not */
        video_unregister_device(isi->vdev);
+       isi->vdev = NULL;
 }
 
 static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
@@ -1323,6 +1326,8 @@ static void atmel_isi_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
        v4l2_async_nf_unregister(&isi->notifier);
        v4l2_async_nf_cleanup(&isi->notifier);
+       if (isi->vdev)
+               video_device_release(isi->vdev);
        v4l2_device_unregister(&isi->v4l2_dev);
 }
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to