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

Commit 9313469f authored by Prakash Gupta's avatar Prakash Gupta Committed by Gerrit - the friendly Code Review server
Browse files

ion: fix memory leak with non cp flag based ion alloc



At present, if ion allocation is done with ION_FLAG_SECURE without setting
any ION_FLAG_CP*, this can result in an ion leak.

Below is the sequence which will result in cma memory leak.

ion_secure_cma_allocate() //flags = ION_FLAG_SECURE |
ION_FLAG_ALLOW_NON_CONTIG
- ion_cma_allocate() //success
- ion_hyp_assign_sg_from_flags()
	- populate_vm_list() //success
	- ion_hyp_assign_sg() //dest_nelems <=0, returns -EINVAL
- ion_secure_cma_free()
	- ion_hyp_unassign_sg_from_flags()
		- populate_vm_list() //success
		- ion_hyp_unassign_sg() // source_nelems <=0,
		  returns -EINVAL
	- ion_cma_free() <= not called

Fix it by freeing the allocated memory if hyp_assign has not failed.

Change-Id: I9d563dd06ae996cc879e65bc50da4cd8a5054f43
Signed-off-by: default avatarPrakash Gupta <guptap@codeaurora.org>
parent 1e4a5e3b
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * Copyright (C) Linaro 2012
 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
 *
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/device.h>
@@ -150,6 +150,9 @@ static int ion_secure_cma_allocate(struct ion_heap *heap,
{
	int ret;

	if (!(flags & ION_FLAGS_CP_MASK))
		return -EINVAL;

	ret = ion_cma_allocate(heap, buffer, len, flags);
	if (ret) {
		dev_err(heap->priv, "Unable to allocate cma buffer");
@@ -157,8 +160,14 @@ static int ion_secure_cma_allocate(struct ion_heap *heap,
	}

	ret = ion_hyp_assign_sg_from_flags(buffer->sg_table, flags, true);
	if (ret)
	if (ret) {
		if (ret == -EADDRNOTAVAIL) {
			goto out_free_buf;
		} else {
			ion_cma_free(buffer);
			goto out;
		}
	}

	return ret;

+3 −0
Original line number Diff line number Diff line
@@ -77,6 +77,9 @@ static int populate_vm_list(unsigned long flags, unsigned int *vm_list,
	int vmid;

	flags = flags & ION_FLAGS_CP_MASK;
	if (!flags)
		return -EINVAL;

	for_each_set_bit(itr, &flags, BITS_PER_LONG) {
		vmid = get_vmid(0x1UL << itr);
		if (vmid < 0 || !nelems)