media: camss: fix memory leaks on error handling paths in probe
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>
This commit is contained in:

committed by
Mauro Carvalho Chehab

parent
602649eada
commit
f45882cfb1
@@ -504,7 +504,6 @@ static int camss_of_parse_ports(struct camss *camss)
|
|||||||
return num_subdevs;
|
return num_subdevs;
|
||||||
|
|
||||||
err_cleanup:
|
err_cleanup:
|
||||||
v4l2_async_notifier_cleanup(&camss->notifier);
|
|
||||||
of_node_put(node);
|
of_node_put(node);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -835,29 +834,38 @@ static int camss_probe(struct platform_device *pdev)
|
|||||||
camss->csid_num = 4;
|
camss->csid_num = 4;
|
||||||
camss->vfe_num = 2;
|
camss->vfe_num = 2;
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
|
camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
|
||||||
sizeof(*camss->csiphy), GFP_KERNEL);
|
sizeof(*camss->csiphy), GFP_KERNEL);
|
||||||
if (!camss->csiphy)
|
if (!camss->csiphy) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
|
camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!camss->csid)
|
if (!camss->csid) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
|
camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!camss->vfe)
|
if (!camss->vfe) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
v4l2_async_notifier_init(&camss->notifier);
|
v4l2_async_notifier_init(&camss->notifier);
|
||||||
|
|
||||||
num_subdevs = camss_of_parse_ports(camss);
|
num_subdevs = camss_of_parse_ports(camss);
|
||||||
if (num_subdevs < 0)
|
if (num_subdevs < 0) {
|
||||||
return num_subdevs;
|
ret = num_subdevs;
|
||||||
|
goto err_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
ret = camss_init_subdevices(camss);
|
ret = camss_init_subdevices(camss);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -936,6 +944,8 @@ err_register_entities:
|
|||||||
v4l2_device_unregister(&camss->v4l2_dev);
|
v4l2_device_unregister(&camss->v4l2_dev);
|
||||||
err_cleanup:
|
err_cleanup:
|
||||||
v4l2_async_notifier_cleanup(&camss->notifier);
|
v4l2_async_notifier_cleanup(&camss->notifier);
|
||||||
|
err_free:
|
||||||
|
kfree(camss);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user