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

Commit 7dc36724 authored by Mohammed Javid's avatar Mohammed Javid Committed by Mohammed Javid
Browse files

msm:ipa: Fix to incorrect structure access



Accessing of incorrect structure pointer is causing
memory out of bound access, fixed issue by accessing
the correct structure pointer.

Change-Id: I3c2f5f7a97cac854093ef670184d06db4231f5e1
Acked-by: default avatarAshok Vuyyuru <avuyyuru@qti.qualcomm.com>
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent 827c6ada
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -1027,7 +1027,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
				goto error;
			}

			if (rt_tbl->cookie != IPA_COOKIE) {
			if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
				IPAERR("RT table cookie is invalid\n");
				goto error;
			}
@@ -1048,7 +1048,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
	}
	INIT_LIST_HEAD(&entry->link);
	entry->rule = *rule;
	entry->cookie = IPA_COOKIE;
	entry->cookie = IPA_FLT_COOKIE;
	entry->rt_tbl = rt_tbl;
	entry->tbl = tbl;
	if (add_rear) {
@@ -1067,13 +1067,19 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
	if (id < 0) {
		IPAERR("failed to add to tree\n");
		WARN_ON(1);
		goto ipa_insert_failed;
	}
	*rule_hdl = id;
	entry->id = id;
	IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);

	return 0;

ipa_insert_failed:
	tbl->rule_cnt--;
	if (entry->rt_tbl)
		entry->rt_tbl->ref_cnt--;
	list_del(&entry->link);
	kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
error:
	return -EPERM;
}
@@ -1089,7 +1095,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
		return -EINVAL;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_FLT_COOKIE) {
		IPAERR("bad params\n");
		return -EINVAL;
	}
@@ -1121,7 +1127,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
		goto error;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_FLT_COOKIE) {
		IPAERR("bad params\n");
		goto error;
	}
@@ -1142,7 +1148,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
				goto error;
			}

			if (rt_tbl->cookie != IPA_COOKIE) {
			if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
				IPAERR("RT table cookie is invalid\n");
				goto error;
			}
+29 −10
Original line number Diff line number Diff line
@@ -547,7 +547,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
{
	struct ipa_hdr_entry *hdr_entry;
	struct ipa_hdr_proc_ctx_entry *entry;
	struct ipa_hdr_proc_ctx_offset_entry *offset;
	struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
	u32 bin;
	struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
	int id;
@@ -563,7 +563,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
	}

	hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
	if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
	if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
		IPAERR("hdr_hdl is invalid\n");
		return -EINVAL;
	}
@@ -580,7 +580,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
	entry->hdr = hdr_entry;
	if (add_ref_hdr)
		hdr_entry->ref_cnt++;
	entry->cookie = IPA_COOKIE;
	entry->cookie = IPA_PROC_HDR_COOKIE;

	needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
			sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@@ -640,6 +640,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
	if (id < 0) {
		IPAERR("failed to alloc id\n");
		WARN_ON(1);
		goto ipa_insert_failed;
	}
	entry->id = id;
	proc_ctx->proc_ctx_hdl = id;
@@ -647,6 +648,14 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,

	return 0;

ipa_insert_failed:
	if (offset)
		list_move(&offset->link,
		&htbl->head_free_offset_list[offset->bin]);
	entry->offset_entry = NULL;
	list_del(&entry->link);
	htbl->proc_ctx_cnt--;

bad_len:
	if (add_ref_hdr)
		hdr_entry->ref_cnt--;
@@ -659,7 +668,7 @@ bad_len:
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
	struct ipa_hdr_entry *entry;
	struct ipa_hdr_offset_entry *offset;
	struct ipa_hdr_offset_entry *offset = NULL;
	u32 bin;
	struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
	int id;
@@ -691,7 +700,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
	entry->type = hdr->type;
	entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
	entry->eth2_ofst = hdr->eth2_ofst;
	entry->cookie = IPA_COOKIE;
	entry->cookie = IPA_HDR_COOKIE;

	if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
		bin = IPA_HDR_BIN0;
@@ -780,6 +789,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
	if (id < 0) {
		IPAERR("failed to alloc id\n");
		WARN_ON(1);
		goto ipa_insert_failed;
	}
	entry->id = id;
	hdr->hdr_hdl = id;
@@ -804,10 +814,19 @@ fail_add_proc_ctx:
	entry->ref_cnt--;
	hdr->hdr_hdl = 0;
	ipa_id_remove(id);
	htbl->hdr_cnt--;
	list_del(&entry->link);
ipa_insert_failed:
	if (entry->is_hdr_proc_ctx) {
		dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
			entry->hdr_len, DMA_TO_DEVICE);
	} else {
		if (offset)
			list_move(&offset->link,
			&htbl->head_free_offset_list[offset->bin]);
		entry->offset_entry = NULL;
	}
	htbl->hdr_cnt--;
	list_del(&entry->link);

fail_dma_mapping:
	entry->is_hdr_proc_ctx = false;
bad_hdr_len:
@@ -824,7 +843,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
	struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;

	entry = ipa_id_find(proc_ctx_hdl);
	if (!entry || (entry->cookie != IPA_COOKIE)) {
	if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
		IPAERR("bad parm\n");
		return -EINVAL;
	}
@@ -875,7 +894,7 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
		return -EINVAL;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_HDR_COOKIE) {
		IPAERR("bad parm\n");
		return -EINVAL;
	}
@@ -1444,7 +1463,7 @@ int ipa2_put_hdr(u32 hdr_hdl)
		goto bail;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_HDR_COOKIE) {
		IPAERR("invalid header entry\n");
		result = -EINVAL;
		goto bail;
+13 −5
Original line number Diff line number Diff line
@@ -37,7 +37,15 @@

#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"

#define IPA_COOKIE 0x57831603
#define IPA_RT_RULE_COOKIE 0x57831604
#define IPA_RT_TBL_COOKIE 0x57831605
#define IPA_FLT_COOKIE 0x57831606
#define IPA_HDR_COOKIE 0x57831607
#define IPA_PROC_HDR_COOKIE 0x57831608


#define MTU_BYTE 1500

#define IPA_MAX_NUM_PIPES 0x14
@@ -223,8 +231,8 @@ struct ipa_smmu_cb_ctx {
 */
struct ipa_flt_entry {
	struct list_head link;
	struct ipa_flt_rule rule;
	u32 cookie;
	struct ipa_flt_rule rule;
	struct ipa_flt_tbl *tbl;
	struct ipa_rt_tbl *rt_tbl;
	u32 hw_len;
@@ -249,13 +257,13 @@ struct ipa_flt_entry {
 */
struct ipa_rt_tbl {
	struct list_head link;
	u32 cookie;
	struct list_head head_rt_rule_list;
	char name[IPA_RESOURCE_NAME_MAX];
	u32 idx;
	u32 rule_cnt;
	u32 ref_cnt;
	struct ipa_rt_tbl_set *set;
	u32 cookie;
	bool in_sys;
	u32 sz;
	struct ipa_mem_buffer curr_mem;
@@ -286,6 +294,7 @@ struct ipa_rt_tbl {
 */
struct ipa_hdr_entry {
	struct list_head link;
	u32 cookie;
	u8 hdr[IPA_HDR_MAX_SIZE];
	u32 hdr_len;
	char name[IPA_RESOURCE_NAME_MAX];
@@ -295,7 +304,6 @@ struct ipa_hdr_entry {
	dma_addr_t phys_base;
	struct ipa_hdr_proc_ctx_entry *proc_ctx;
	struct ipa_hdr_offset_entry *offset_entry;
	u32 cookie;
	u32 ref_cnt;
	int id;
	u8 is_eth2_ofst_valid;
@@ -368,10 +376,10 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
 */
struct ipa_hdr_proc_ctx_entry {
	struct list_head link;
	u32 cookie;
	enum ipa_hdr_proc_type type;
	struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
	struct ipa_hdr_entry *hdr;
	u32 cookie;
	u32 ref_cnt;
	int id;
	bool user_deleted;
@@ -427,8 +435,8 @@ struct ipa_flt_tbl {
 */
struct ipa_rt_entry {
	struct list_head link;
	struct ipa_rt_rule rule;
	u32 cookie;
	struct ipa_rt_rule rule;
	struct ipa_rt_tbl *tbl;
	struct ipa_hdr_entry *hdr;
	struct ipa_hdr_proc_ctx_entry *proc_ctx;
+24 −13
Original line number Diff line number Diff line
@@ -905,7 +905,7 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
		INIT_LIST_HEAD(&entry->link);
		strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
		entry->set = set;
		entry->cookie = IPA_COOKIE;
		entry->cookie = IPA_RT_TBL_COOKIE;
		entry->in_sys = (ip == IPA_IP_v4) ?
			!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
		set->tbl_cnt++;
@@ -918,12 +918,16 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
		if (id < 0) {
			IPAERR("failed to add to tree\n");
			WARN_ON(1);
			goto ipa_insert_failed;
		}
		entry->id = id;
	}

	return entry;

ipa_insert_failed:
	set->tbl_cnt--;
	list_del(&entry->link);
fail_rt_idx_alloc:
	entry->cookie = 0;
	kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@@ -936,7 +940,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
	enum ipa_ip_type ip = IPA_IP_MAX;
	u32 id;

	if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
	if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
		IPAERR("bad parms\n");
		return -EINVAL;
	}
@@ -950,8 +954,11 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
		ip = IPA_IP_v4;
	else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
		ip = IPA_IP_v6;
	else
	else {
		WARN_ON(1);
		return -EPERM;
	}


	if (!entry->in_sys) {
		list_del(&entry->link);
@@ -990,13 +997,14 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,

	if (rule->hdr_hdl) {
		hdr = ipa_id_find(rule->hdr_hdl);
		if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
		if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
			IPAERR("rt rule does not point to valid hdr\n");
			goto error;
		}
	} else if (rule->hdr_proc_ctx_hdl) {
		proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
		if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
		if ((proc_ctx == NULL) ||
			(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
			IPAERR("rt rule does not point to valid proc ctx\n");
			goto error;
		}
@@ -1004,7 +1012,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,


	tbl = __ipa_add_rt_tbl(ip, name);
	if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
	if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
		IPAERR("bad params\n");
		goto error;
	}
@@ -1025,7 +1033,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
		goto error;
	}
	INIT_LIST_HEAD(&entry->link);
	entry->cookie = IPA_COOKIE;
	entry->cookie = IPA_RT_RULE_COOKIE;
	entry->rule = *rule;
	entry->tbl = tbl;
	entry->hdr = hdr;
@@ -1119,7 +1127,7 @@ int __ipa_del_rt_rule(u32 rule_hdl)
		return -EINVAL;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_RT_RULE_COOKIE) {
		IPAERR("bad params\n");
		return -EINVAL;
	}
@@ -1354,7 +1362,7 @@ int ipa2_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
	}
	mutex_lock(&ipa_ctx->lock);
	entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
	if (entry && entry->cookie == IPA_COOKIE) {
	if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
		if (entry->ref_cnt == U32_MAX) {
			IPAERR("fail: ref count crossed limit\n");
			goto ret;
@@ -1397,7 +1405,7 @@ int ipa2_put_rt_tbl(u32 rt_tbl_hdl)
		goto ret;
	}

	if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
	if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
		IPAERR("bad parms\n");
		result = -EINVAL;
		goto ret;
@@ -1407,8 +1415,11 @@ int ipa2_put_rt_tbl(u32 rt_tbl_hdl)
		ip = IPA_IP_v4;
	else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
		ip = IPA_IP_v6;
	else
	else {
		WARN_ON(1);
		result = -EINVAL;
		goto ret;
	}

	entry->ref_cnt--;
	if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1435,7 +1446,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)

	if (rtrule->rule.hdr_hdl) {
		hdr = ipa_id_find(rtrule->rule.hdr_hdl);
		if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
		if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
			IPAERR("rt rule does not point to valid hdr\n");
			goto error;
		}
@@ -1447,7 +1458,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
		goto error;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_RT_RULE_COOKIE) {
		IPAERR("bad params\n");
		goto error;
	}
+30 −7
Original line number Diff line number Diff line
@@ -1084,7 +1084,7 @@ static int __ipa_validate_flt_rule(const struct ipa_flt_rule *rule,
				goto error;
			}

			if ((*rt_tbl)->cookie != IPA_COOKIE) {
			if ((*rt_tbl)->cookie != IPA_RT_TBL_COOKIE) {
				IPAERR("RT table cookie is invalid\n");
				goto error;
			}
@@ -1129,7 +1129,7 @@ static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry,
	}
	INIT_LIST_HEAD(&((*entry)->link));
	(*entry)->rule = *rule;
	(*entry)->cookie = IPA_COOKIE;
	(*entry)->cookie = IPA_FLT_COOKIE;
	(*entry)->rt_tbl = rt_tbl;
	(*entry)->tbl = tbl;
	if (rule->rule_id) {
@@ -1164,12 +1164,18 @@ static int __ipa_finish_flt_rule_add(struct ipa3_flt_tbl *tbl,
	if (id < 0) {
		IPAERR("failed to add to tree\n");
		WARN_ON(1);
		goto ipa_insert_failed;
	}
	*rule_hdl = id;
	entry->id = id;
	IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);

	return 0;
ipa_insert_failed:
	if (entry->rt_tbl)
		entry->rt_tbl->ref_cnt--;
	tbl->rule_cnt--;
	return -EPERM;
}

static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
@@ -1195,9 +1201,17 @@ static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
		list_add(&entry->link, &tbl->head_flt_rule_list);
	}

	__ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
	if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
		goto ipa_insert_failed;

	return 0;
ipa_insert_failed:
	list_del(&entry->link);
	/* if rule id was allocated from idr, remove it */
	if (entry->rule_id >= IPA_RULE_ID_MIN_VAL &&
	    entry->rule_id <= IPA_RULE_ID_MAX_VAL)
		idr_remove(&entry->tbl->rule_ids, entry->rule_id);
	kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);

error:
	return -EPERM;
@@ -1229,7 +1243,8 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,

	list_add(&entry->link, &((*add_after_entry)->link));

	__ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
	if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
		goto ipa_insert_failed;

	/*
	 * prepare for next insertion
@@ -1238,6 +1253,14 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,

	return 0;

ipa_insert_failed:
	list_del(&entry->link);
	/* if rule id was allocated from idr, remove it */
	if (entry->rule_id >= IPA_RULE_ID_MIN_VAL &&
	    entry->rule_id <= IPA_RULE_ID_MAX_VAL)
		idr_remove(&entry->tbl->rule_ids, entry->rule_id);
	kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);

error:
	*add_after_entry = NULL;
	return -EPERM;
@@ -1254,7 +1277,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
		return -EINVAL;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_FLT_COOKIE) {
		IPAERR("bad params\n");
		return -EINVAL;
	}
@@ -1291,7 +1314,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
		goto error;
	}

	if (entry->cookie != IPA_COOKIE) {
	if (entry->cookie != IPA_FLT_COOKIE) {
		IPAERR("bad params\n");
		goto error;
	}
@@ -1312,7 +1335,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
				goto error;
			}

			if (rt_tbl->cookie != IPA_COOKIE) {
			if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
				IPAERR("RT table cookie is invalid\n");
				goto error;
			}
Loading