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

Commit d0a8bc69 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: fix ioctl input param validation"

parents 64120cd2 d12370c7
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 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
@@ -235,7 +235,7 @@ static int ipa_generate_flt_hw_rule(enum ipa_ip_type ip,
 * @ip: the ip address family type
 * @hdr_sz: header size
 *
 * Returns:	0 on success, negative on failure
 * Returns:	size on success, negative on failure
 *
 * caller needs to hold any needed locks to ensure integrity
 *
@@ -373,7 +373,12 @@ static int ipa_generate_flt_hw_tbl_common(enum ipa_ip_type ip, u8 *base,
					((long)body &
					IPA_FLT_ENTRY_MEMORY_ALLIGNMENT));
		} else {
			WARN_ON(tbl->sz == 0);
			if (tbl->sz == 0) {
				IPAERR("tbl size is 0\n");
				WARN_ON(1);
				goto proc_err;
			}

			/* allocate memory for the flt tbl */
			flt_tbl_mem.size = tbl->sz;
			flt_tbl_mem.base =
@@ -460,7 +465,12 @@ static int ipa_generate_flt_hw_tbl_common(enum ipa_ip_type ip, u8 *base,
						((long)body &
					IPA_FLT_ENTRY_MEMORY_ALLIGNMENT));
			} else {
				WARN_ON(tbl->sz == 0);
				if (tbl->sz == 0) {
					IPAERR("tbl size is 0\n");
					WARN_ON(1);
					goto proc_err;
				}

				/* allocate memory for the flt tbl */
				flt_tbl_mem.size = tbl->sz;
				flt_tbl_mem.base =
@@ -534,8 +544,15 @@ static int ipa_generate_flt_hw_tbl_v1_1(enum ipa_ip_type ip,
	u8 *hdr;
	u8 *body;
	u8 *base;
	int res;

	res = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
	if (res < 0) {
		IPAERR("ipa_get_flt_hw_tbl_size failed %d\n", res);
		return res;
	}

	mem->size = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
	mem->size = res;
	mem->size = IPA_HW_TABLE_ALIGNMENT(mem->size);

	if (mem->size == 0) {
@@ -720,6 +737,7 @@ static int ipa_generate_flt_hw_tbl_v2(enum ipa_ip_type ip,
	u32 *entr;
	u32 body_start_offset;
	u32 hdr_top;
	int res;

	if (ip == IPA_IP_v4)
		body_start_offset = IPA_MEM_PART(apps_v4_flt_ofst) -
@@ -756,7 +774,13 @@ static int ipa_generate_flt_hw_tbl_v2(enum ipa_ip_type ip,
		entr++;
	}

	mem->size = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
	res = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
	if (res < 0) {
		IPAERR("ipa_get_flt_hw_tbl_size failed %d\n", res);
		goto body_err;
	}

	mem->size = res;
	mem->size -= hdr_sz;
	mem->size = IPA_HW_TABLE_ALIGNMENT(mem->size);

+1 −1
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@

#define IPA_HW_TABLE_ALIGNMENT(start_ofst) \
	(((start_ofst) + 127) & ~127)
#define IPA_RT_FLT_HW_RULE_BUF_SIZE	(128)
#define IPA_RT_FLT_HW_RULE_BUF_SIZE	(256)

#define IPA_HDR_PROC_CTX_TABLE_ALIGNMENT_BYTE 8
#define IPA_HDR_PROC_CTX_TABLE_ALIGNMENT(start_ofst) \
+76 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 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
@@ -25,6 +25,16 @@
#define IPA_NAT_SHARED_MEMORY  1
#define IPA_NAT_TEMP_MEM_SIZE 128

enum nat_table_type {
	IPA_NAT_BASE_TBL = 0,
	IPA_NAT_EXPN_TBL = 1,
	IPA_NAT_INDX_TBL = 2,
	IPA_NAT_INDEX_EXPN_TBL = 3,
};

#define NAT_TABLE_ENTRY_SIZE_BYTE 32
#define NAT_INTEX_TABLE_ENTRY_SIZE_BYTE 4

static int ipa_nat_vma_fault_remap(
	 struct vm_area_struct *vma, struct vm_fault *vmf)
{
@@ -568,6 +578,71 @@ int ipa2_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
		goto bail;
	}

	for (cnt = 0; cnt < dma->entries; cnt++) {
		if (dma->dma[cnt].table_index >= 1) {
			IPAERR("Invalid table index %d\n",
				dma->dma[cnt].table_index);
			ret = -EPERM;
			goto bail;
		}

		switch (dma->dma[cnt].base_addr) {
		case IPA_NAT_BASE_TBL:
			if (dma->dma[cnt].offset >=
				(ipa_ctx->nat_mem.size_base_tables + 1) *
				NAT_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		case IPA_NAT_EXPN_TBL:
			if (dma->dma[cnt].offset >=
				ipa_ctx->nat_mem.size_expansion_tables *
				NAT_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		case IPA_NAT_INDX_TBL:
			if (dma->dma[cnt].offset >=
				(ipa_ctx->nat_mem.size_base_tables + 1) *
				NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		case IPA_NAT_INDEX_EXPN_TBL:
			if (dma->dma[cnt].offset >=
				ipa_ctx->nat_mem.size_expansion_tables *
				NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		default:
			IPAERR("Invalid base_addr %d\n",
				dma->dma[cnt].base_addr);
			ret = -EPERM;
			goto bail;
		}
	}

	size = sizeof(struct ipa_desc) * NUM_OF_DESC;
	desc = kzalloc(size, GFP_KERNEL);
	if (desc == NULL) {
+22 −4
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ int __ipa_generate_rt_hw_rule_v2_6L(enum ipa_ip_type ip,
 * @hdr_sz: header size
 * @max_rt_idx: maximal index
 *
 * Returns:	0 on success, negative on failure
 * Returns:	size on success, negative on failure
 *
 * caller needs to hold any needed locks to ensure integrity
 *
@@ -356,7 +356,11 @@ static int ipa_generate_rt_hw_tbl_common(enum ipa_ip_type ip, u8 *base, u8 *hdr,
					      ((long)body &
					      IPA_RT_ENTRY_MEMORY_ALLIGNMENT));
		} else {
			WARN_ON(tbl->sz == 0);
			if (tbl->sz == 0) {
				IPAERR("cannot generate 0 size table\n");
				goto proc_err;
			}

			/* allocate memory for the RT tbl */
			rt_tbl_mem.size = tbl->sz;
			rt_tbl_mem.base =
@@ -429,8 +433,15 @@ static int ipa_generate_rt_hw_tbl_v1_1(enum ipa_ip_type ip,
	u8 *base;
	int max_rt_idx;
	int i;
	int res;

	res = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
	if (res < 0) {
		IPAERR("ipa_get_rt_hw_tbl_size failed %d\n", res);
		goto error;
	}

	mem->size = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
	mem->size = res;
	mem->size = (mem->size + IPA_RT_TABLE_MEMORY_ALLIGNMENT) &
				~IPA_RT_TABLE_MEMORY_ALLIGNMENT;

@@ -603,6 +614,7 @@ static int ipa_generate_rt_hw_tbl_v2(enum ipa_ip_type ip,
	int num_index;
	u32 body_start_offset;
	u32 apps_start_idx;
	int res;

	if (ip == IPA_IP_v4) {
		num_index = IPA_MEM_PART(v4_apps_rt_index_hi) -
@@ -632,7 +644,13 @@ static int ipa_generate_rt_hw_tbl_v2(enum ipa_ip_type ip,
		entr++;
	}

	mem->size = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
	res = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
	if (res < 0) {
		IPAERR("ipa_get_rt_hw_tbl_size failed %d\n", res);
		goto base_err;
	}

	mem->size = res;
	mem->size -= hdr_sz;
	mem->size = (mem->size + IPA_RT_TABLE_MEMORY_ALLIGNMENT) &
				~IPA_RT_TABLE_MEMORY_ALLIGNMENT;
+76 −0
Original line number Diff line number Diff line
@@ -24,6 +24,17 @@

#define IPA_NAT_TEMP_MEM_SIZE 128

enum nat_table_type {
	IPA_NAT_BASE_TBL = 0,
	IPA_NAT_EXPN_TBL = 1,
	IPA_NAT_INDX_TBL = 2,
	IPA_NAT_INDEX_EXPN_TBL = 3,
};

#define NAT_TABLE_ENTRY_SIZE_BYTE 32
#define NAT_INTEX_TABLE_ENTRY_SIZE_BYTE 4


static int ipa3_nat_vma_fault_remap(
	 struct vm_area_struct *vma, struct vm_fault *vmf)
{
@@ -571,6 +582,71 @@ int ipa3_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
		goto bail;
	}

	for (cnt = 0; cnt < dma->entries; cnt++) {
		if (dma->dma[cnt].table_index >= 1) {
			IPAERR("Invalid table index %d\n",
				dma->dma[cnt].table_index);
			ret = -EPERM;
			goto bail;
		}

		switch (dma->dma[cnt].base_addr) {
		case IPA_NAT_BASE_TBL:
			if (dma->dma[cnt].offset >=
				(ipa3_ctx->nat_mem.size_base_tables + 1) *
				NAT_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		case IPA_NAT_EXPN_TBL:
			if (dma->dma[cnt].offset >=
				ipa3_ctx->nat_mem.size_expansion_tables *
				NAT_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		case IPA_NAT_INDX_TBL:
			if (dma->dma[cnt].offset >=
				(ipa3_ctx->nat_mem.size_base_tables + 1) *
				NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		case IPA_NAT_INDEX_EXPN_TBL:
			if (dma->dma[cnt].offset >=
				ipa3_ctx->nat_mem.size_expansion_tables *
				NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
				IPAERR("Invalid offset %d\n",
					dma->dma[cnt].offset);
				ret = -EPERM;
				goto bail;
			}

			break;

		default:
			IPAERR("Invalid base_addr %d\n",
				dma->dma[cnt].base_addr);
			ret = -EPERM;
			goto bail;
		}
	}

	size = sizeof(struct ipa3_desc) * NUM_OF_DESC;
	desc = kzalloc(size, GFP_KERNEL);
	if (desc == NULL) {