[PATCH v8 05/16] media: cadence: csi2rx: Unregister v4l2 async notifier

Jai Luthra posted 16 patches 2 years, 6 months ago
There is a newer version of this series
[PATCH v8 05/16] media: cadence: csi2rx: Unregister v4l2 async notifier
Posted by Jai Luthra 2 years, 6 months ago
From: Pratyush Yadav <p.yadav@ti.com>

The notifier is added to the global notifier list when registered. When
the module is removed, the struct csi2rx_priv in which the notifier is
embedded, is destroyed. As a result the notifier list has a reference to
a notifier that no longer exists. This causes invalid memory accesses
when the list is iterated over. Similar for when the probe fails.
Unregister and clean up the notifier to avoid this.

Fixes: 1fc3b37f34f6 ("media: v4l: cadence: Add Cadence MIPI-CSI2 RX driver")

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Signed-off-by: Jai Luthra <j-luthra@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v7->v8: No change

 drivers/media/platform/cadence/cdns-csi2rx.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index b087583d636f..fd6f2e04e77f 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -479,8 +479,10 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
 	asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh,
 					      struct v4l2_async_connection);
 	of_node_put(ep);
-	if (IS_ERR(asd))
+	if (IS_ERR(asd)) {
+		v4l2_async_nf_cleanup(&csi2rx->notifier);
 		return PTR_ERR(asd);
+	}
 
 	csi2rx->notifier.ops = &csi2rx_notifier_ops;
 
@@ -543,6 +545,7 @@ static int csi2rx_probe(struct platform_device *pdev)
 	return 0;
 
 err_cleanup:
+	v4l2_async_nf_unregister(&csi2rx->notifier);
 	v4l2_async_nf_cleanup(&csi2rx->notifier);
 err_free_priv:
 	kfree(csi2rx);
@@ -553,6 +556,8 @@ static void csi2rx_remove(struct platform_device *pdev)
 {
 	struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev);
 
+	v4l2_async_nf_unregister(&csi2rx->notifier);
+	v4l2_async_nf_cleanup(&csi2rx->notifier);
 	v4l2_async_unregister_subdev(&csi2rx->subdev);
 	kfree(csi2rx);
 }

-- 
2.41.0
Re: [PATCH v8 05/16] media: cadence: csi2rx: Unregister v4l2 async notifier
Posted by Tomi Valkeinen 2 years, 6 months ago
On 31/07/2023 11:29, Jai Luthra wrote:
> From: Pratyush Yadav <p.yadav@ti.com>
> 
> The notifier is added to the global notifier list when registered. When
> the module is removed, the struct csi2rx_priv in which the notifier is
> embedded, is destroyed. As a result the notifier list has a reference to
> a notifier that no longer exists. This causes invalid memory accesses
> when the list is iterated over. Similar for when the probe fails.
> Unregister and clean up the notifier to avoid this.
> 
> Fixes: 1fc3b37f34f6 ("media: v4l: cadence: Add Cadence MIPI-CSI2 RX driver")
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> Signed-off-by: Jai Luthra <j-luthra@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> v7->v8: No change
> 
>   drivers/media/platform/cadence/cdns-csi2rx.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index b087583d636f..fd6f2e04e77f 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -479,8 +479,10 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
>   	asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh,
>   					      struct v4l2_async_connection);
>   	of_node_put(ep);
> -	if (IS_ERR(asd))
> +	if (IS_ERR(asd)) {
> +		v4l2_async_nf_cleanup(&csi2rx->notifier);
>   		return PTR_ERR(asd);
> +	}
>   
>   	csi2rx->notifier.ops = &csi2rx_notifier_ops;
>   
> @@ -543,6 +545,7 @@ static int csi2rx_probe(struct platform_device *pdev)
>   	return 0;
>   
>   err_cleanup:
> +	v4l2_async_nf_unregister(&csi2rx->notifier);
>   	v4l2_async_nf_cleanup(&csi2rx->notifier);
>   err_free_priv:
>   	kfree(csi2rx);
> @@ -553,6 +556,8 @@ static void csi2rx_remove(struct platform_device *pdev)
>   {
>   	struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev);
>   
> +	v4l2_async_nf_unregister(&csi2rx->notifier);
> +	v4l2_async_nf_cleanup(&csi2rx->notifier);
>   	v4l2_async_unregister_subdev(&csi2rx->subdev);
>   	kfree(csi2rx);
>   }
> 

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

  Tomi