Commit 3e4afbb1 authored by zhengbin's avatar zhengbin Committed by Greg Kroah-Hartman

media: mc-device.c: fix memleak in media_device_register_entity

[ Upstream commit 713f871b ]

In media_device_register_entity, if media_graph_walk_init fails,
need to free the previously memory.
Reported-by: default avatarHulk Robot <hulkci@huawei.com>
Signed-off-by: default avatarzhengbin <zhengbin13@huawei.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 1904f6df
......@@ -568,6 +568,38 @@ static void media_device_release(struct media_devnode *devnode)
dev_dbg(devnode->parent, "Media device released\n");
}
static void __media_device_unregister_entity(struct media_entity *entity)
{
struct media_device *mdev = entity->graph_obj.mdev;
struct media_link *link, *tmp;
struct media_interface *intf;
unsigned int i;
ida_free(&mdev->entity_internal_idx, entity->internal_idx);
/* Remove all interface links pointing to this entity */
list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
list_for_each_entry_safe(link, tmp, &intf->links, list) {
if (link->entity == entity)
__media_remove_intf_link(link);
}
}
/* Remove all data links that belong to this entity */
__media_entity_remove_links(entity);
/* Remove all pads that belong to this entity */
for (i = 0; i < entity->num_pads; i++)
media_gobj_destroy(&entity->pads[i].graph_obj);
/* Remove the entity */
media_gobj_destroy(&entity->graph_obj);
/* invoke entity_notify callbacks to handle entity removal?? */
entity->graph_obj.mdev = NULL;
}
/**
* media_device_register_entity - Register an entity with a media device
* @mdev: The media device
......@@ -625,6 +657,7 @@ int __must_check media_device_register_entity(struct media_device *mdev,
*/
ret = media_graph_walk_init(&new, mdev);
if (ret) {
__media_device_unregister_entity(entity);
mutex_unlock(&mdev->graph_mutex);
return ret;
}
......@@ -637,38 +670,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,
}
EXPORT_SYMBOL_GPL(media_device_register_entity);
static void __media_device_unregister_entity(struct media_entity *entity)
{
struct media_device *mdev = entity->graph_obj.mdev;
struct media_link *link, *tmp;
struct media_interface *intf;
unsigned int i;
ida_free(&mdev->entity_internal_idx, entity->internal_idx);
/* Remove all interface links pointing to this entity */
list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
list_for_each_entry_safe(link, tmp, &intf->links, list) {
if (link->entity == entity)
__media_remove_intf_link(link);
}
}
/* Remove all data links that belong to this entity */
__media_entity_remove_links(entity);
/* Remove all pads that belong to this entity */
for (i = 0; i < entity->num_pads; i++)
media_gobj_destroy(&entity->pads[i].graph_obj);
/* Remove the entity */
media_gobj_destroy(&entity->graph_obj);
/* invoke entity_notify callbacks to handle entity removal?? */
entity->graph_obj.mdev = NULL;
}
void media_device_unregister_entity(struct media_entity *entity)
{
struct media_device *mdev = entity->graph_obj.mdev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment