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

Commit 62df6b97 authored by mjavid's avatar mjavid Committed by Pooja Kumari
Browse files

msm: ipa3: Fix memleak issue for IPv6 NAt and IPA CT device



Currently tmp memory is deleted in device destroy method, but
there is no check for NULL. So it can cause for double free issue.

Change-Id: Ide8d8d24c0f9cea68597ecbf6b6b84269062384a
Acked-by: default avatarPooja Kumari <kumarip@qti.qualcomm.com>
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent 573e6b5f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1076,6 +1076,7 @@ struct ipa3_nat_ipv6ct_common_mem {
 * @index_table_expansion_addr: index expansion table address
 * @public_ip_addr: ip address of nat table
 * @pdn_mem: pdn config table SW cache memory structure
 * @is_tmp_mem_allocated: indicate if tmp mem has been allocated
 */
struct ipa3_nat_mem {
	struct ipa3_nat_ipv6ct_common_mem dev;
@@ -1083,6 +1084,7 @@ struct ipa3_nat_mem {
	char *index_table_expansion_addr;
	u32 public_ip_addr;
	struct ipa_mem_buffer pdn_mem;
	bool is_tmp_mem_allocated;
};

/**
+20 −7
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -266,14 +266,21 @@ static void ipa3_nat_ipv6ct_destroy_device(

	mutex_lock(&dev->lock);

	if (dev->tmp_mem != NULL &&
		ipa3_ctx->nat_mem.is_tmp_mem_allocated == false) {
		dev->tmp_mem = NULL;
	} else if (dev->tmp_mem != NULL &&
		ipa3_ctx->nat_mem.is_tmp_mem_allocated) {
		dma_free_coherent(ipa3_ctx->pdev, IPA_NAT_IPV6CT_TEMP_MEM_SIZE,
			dev->tmp_mem->vaddr, dev->tmp_mem->dma_handle);
		kfree(dev->tmp_mem);
		dev->tmp_mem = NULL;
		ipa3_ctx->nat_mem.is_tmp_mem_allocated = false;
	}
	device_destroy(dev->class, dev->dev_num);
	unregister_chrdev_region(dev->dev_num, 1);
	class_destroy(dev->class);
	dev->is_dev_init = false;

	mutex_unlock(&dev->lock);

	IPADBG("return\n");
@@ -296,10 +303,15 @@ int ipa3_nat_ipv6ct_init_devices(void)
	/*
	 * Allocate NAT/IPv6CT temporary memory. The memory is never deleted,
	 * because provided to HW once NAT or IPv6CT table is deleted.
	 * NULL is a legal value
	 */
	tmp_mem = ipa3_nat_ipv6ct_allocate_tmp_memory();

	if (tmp_mem == NULL) {
		IPAERR("unable to allocate tmp_mem\n");
		return -ENOMEM;
	}
	ipa3_ctx->nat_mem.is_tmp_mem_allocated = true;

	if (ipa3_nat_ipv6ct_init_device(
		&ipa3_ctx->nat_mem.dev,
		IPA_NAT_DEV_NAME,
@@ -328,10 +340,11 @@ int ipa3_nat_ipv6ct_init_devices(void)
fail_init_ipv6ct_dev:
	ipa3_nat_ipv6ct_destroy_device(&ipa3_ctx->nat_mem.dev);
fail_init_nat_dev:
	if (tmp_mem != NULL) {
	if (tmp_mem != NULL && ipa3_ctx->nat_mem.is_tmp_mem_allocated) {
		dma_free_coherent(ipa3_ctx->pdev, IPA_NAT_IPV6CT_TEMP_MEM_SIZE,
			tmp_mem->vaddr, tmp_mem->dma_handle);
		kfree(tmp_mem);
		ipa3_ctx->nat_mem.is_tmp_mem_allocated = false;
	}
	return result;
}