media: camss: fix memory leaks on error handling paths in probe
authorEvgeny Novikov <novikov@ispras.ru>
Thu, 23 Jul 2020 17:46:51 +0000 (19:46 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Thu, 6 Aug 2020 11:58:40 +0000 (13:58 +0200)
camss_probe() does not free camss on error handling paths. The patch
introduces an additional error label for this purpose. Besides, it
removes call of v4l2_async_notifier_cleanup() from
camss_of_parse_ports() since its caller, camss_probe(), cleans up all
its resources itself.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
Co-developed-by: Anton Vasilyev <vasilyev@ispras.ru>
Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/media/platform/qcom/camss/camss.c

index 3fdc9f9..2483641 100644 (file)
@@ -504,7 +504,6 @@ static int camss_of_parse_ports(struct camss *camss)
        return num_subdevs;
 
 err_cleanup:
-       v4l2_async_notifier_cleanup(&camss->notifier);
        of_node_put(node);
        return ret;
 }
@@ -835,29 +834,38 @@ static int camss_probe(struct platform_device *pdev)
                camss->csid_num = 4;
                camss->vfe_num = 2;
        } else {
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_free;
        }
 
        camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
                                     sizeof(*camss->csiphy), GFP_KERNEL);
-       if (!camss->csiphy)
-               return -ENOMEM;
+       if (!camss->csiphy) {
+               ret = -ENOMEM;
+               goto err_free;
+       }
 
        camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
                                   GFP_KERNEL);
-       if (!camss->csid)
-               return -ENOMEM;
+       if (!camss->csid) {
+               ret = -ENOMEM;
+               goto err_free;
+       }
 
        camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
                                  GFP_KERNEL);
-       if (!camss->vfe)
-               return -ENOMEM;
+       if (!camss->vfe) {
+               ret = -ENOMEM;
+               goto err_free;
+       }
 
        v4l2_async_notifier_init(&camss->notifier);
 
        num_subdevs = camss_of_parse_ports(camss);
-       if (num_subdevs < 0)
-               return num_subdevs;
+       if (num_subdevs < 0) {
+               ret = num_subdevs;
+               goto err_cleanup;
+       }
 
        ret = camss_init_subdevices(camss);
        if (ret < 0)
@@ -936,6 +944,8 @@ err_register_entities:
        v4l2_device_unregister(&camss->v4l2_dev);
 err_cleanup:
        v4l2_async_notifier_cleanup(&camss->notifier);
+err_free:
+       kfree(camss);
 
        return ret;
 }