Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

In media_device_register_entity, if media_graph_walk_init fails,
need to free the previously memory.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: zhengbin <zhengbin13@huawei.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

authored by

zhengbin and committed by
Mauro Carvalho Chehab
713f871b 36909b55

+33 -32
+33 -32
drivers/media/mc/mc-device.c
··· 575 575 dev_dbg(devnode->parent, "Media device released\n"); 576 576 } 577 577 578 + static void __media_device_unregister_entity(struct media_entity *entity) 579 + { 580 + struct media_device *mdev = entity->graph_obj.mdev; 581 + struct media_link *link, *tmp; 582 + struct media_interface *intf; 583 + unsigned int i; 584 + 585 + ida_free(&mdev->entity_internal_idx, entity->internal_idx); 586 + 587 + /* Remove all interface links pointing to this entity */ 588 + list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { 589 + list_for_each_entry_safe(link, tmp, &intf->links, list) { 590 + if (link->entity == entity) 591 + __media_remove_intf_link(link); 592 + } 593 + } 594 + 595 + /* Remove all data links that belong to this entity */ 596 + __media_entity_remove_links(entity); 597 + 598 + /* Remove all pads that belong to this entity */ 599 + for (i = 0; i < entity->num_pads; i++) 600 + media_gobj_destroy(&entity->pads[i].graph_obj); 601 + 602 + /* Remove the entity */ 603 + media_gobj_destroy(&entity->graph_obj); 604 + 605 + /* invoke entity_notify callbacks to handle entity removal?? */ 606 + 607 + entity->graph_obj.mdev = NULL; 608 + } 609 + 578 610 /** 579 611 * media_device_register_entity - Register an entity with a media device 580 612 * @mdev: The media device ··· 664 632 */ 665 633 ret = media_graph_walk_init(&new, mdev); 666 634 if (ret) { 635 + __media_device_unregister_entity(entity); 667 636 mutex_unlock(&mdev->graph_mutex); 668 637 return ret; 669 638 } ··· 676 643 return 0; 677 644 } 678 645 EXPORT_SYMBOL_GPL(media_device_register_entity); 679 - 680 - static void __media_device_unregister_entity(struct media_entity *entity) 681 - { 682 - struct media_device *mdev = entity->graph_obj.mdev; 683 - struct media_link *link, *tmp; 684 - struct media_interface *intf; 685 - unsigned int i; 686 - 687 - ida_free(&mdev->entity_internal_idx, entity->internal_idx); 688 - 689 - /* Remove all interface links pointing to this entity */ 690 - list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { 691 - list_for_each_entry_safe(link, tmp, &intf->links, list) { 692 - if (link->entity == entity) 693 - __media_remove_intf_link(link); 694 - } 695 - } 696 - 697 - /* Remove all data links that belong to this entity */ 698 - __media_entity_remove_links(entity); 699 - 700 - /* Remove all pads that belong to this entity */ 701 - for (i = 0; i < entity->num_pads; i++) 702 - media_gobj_destroy(&entity->pads[i].graph_obj); 703 - 704 - /* Remove the entity */ 705 - media_gobj_destroy(&entity->graph_obj); 706 - 707 - /* invoke entity_notify callbacks to handle entity removal?? */ 708 - 709 - entity->graph_obj.mdev = NULL; 710 - } 711 646 712 647 void media_device_unregister_entity(struct media_entity *entity) 713 648 {