Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25738978 authored by Omar Ramirez Luna's avatar Omar Ramirez Luna Committed by Greg Kroah-Hartman
Browse files

staging: tidspbridge: fix bridge_open memory leaks



There are two members of pr_ctxt allocated during bridge_open that
are never freed resulting in memory leaks, these are stream_id and
node_id, they are now freed on release of the handle (bridge_release)
right before freeing pr_ctxt.

Error path for bridge_open was also fixed since the same variables
could result in memory leaking due to missing handling of failure
scenarios. While at it, the indentation changes were introduced to
avoid interleaved goto statements inside big if blocks.

Signed-off-by: default avatarOmar Ramirez Luna <omar.ramirez@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 00da8edd
Loading
Loading
Loading
Loading
+32 −23
Original line number Diff line number Diff line
@@ -139,7 +139,9 @@ static int bridge_open(struct inode *ip, struct file *filp)
	}
#endif
	pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
	if (pr_ctxt) {
	if (!pr_ctxt)
		return -ENOMEM;

	pr_ctxt->res_state = PROC_RES_ALLOCATED;
	spin_lock_init(&pr_ctxt->dmm_map_lock);
	INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
@@ -147,27 +149,32 @@ static int bridge_open(struct inode *ip, struct file *filp)
	INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);

	pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
		if (pr_ctxt->node_id) {
			idr_init(pr_ctxt->node_id);
		} else {
	if (!pr_ctxt->node_id) {
		status = -ENOMEM;
			goto err;
		goto err1;
	}

	idr_init(pr_ctxt->node_id);

	pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
		if (pr_ctxt->stream_id)
			idr_init(pr_ctxt->stream_id);
		else
			status = -ENOMEM;
	} else {
	if (!pr_ctxt->stream_id) {
		status = -ENOMEM;
		goto err2;
	}
err:

	idr_init(pr_ctxt->stream_id);

	filp->private_data = pr_ctxt;

#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
	if (!status)
	atomic_inc(&bridge_cref);
#endif
	return 0;

err2:
	kfree(pr_ctxt->node_id);
err1:
	kfree(pr_ctxt);
	return status;
}

@@ -189,6 +196,8 @@ static int bridge_release(struct inode *ip, struct file *filp)
	flush_signals(current);
	drv_remove_all_resources(pr_ctxt);
	proc_detach(pr_ctxt);
	kfree(pr_ctxt->node_id);
	kfree(pr_ctxt->stream_id);
	kfree(pr_ctxt);

	filp->private_data = NULL;