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

Commit 806eaf6f authored by Mohammed Javid's avatar Mohammed Javid Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Fix to handle NULL pointer dereference



Header entry deleted but same entry pointer using in
routing table not updated. Added checks to confirm
header entry present or not before using it to avoid
null pointer dereference.

Change-Id: Id1d844c60b2dcb0cc7cf18352b78d62fe5a89347
Acked-by: default avatarAshok Vuyyuru <avuyyuru@qti.qualcomm.com>
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent e6408fea
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ int __ipa_generate_rt_hw_rule_v2(enum ipa_ip_type ip,
	u32 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE/4];
	u8 *start;
	int pipe_idx;
	struct ipa_hdr_entry *hdr_entry;

	if (buf == NULL) {
		memset(tmp, 0, (IPA_RT_FLT_HW_RULE_BUF_SIZE/4));
@@ -74,6 +75,18 @@ int __ipa_generate_rt_hw_rule_v2(enum ipa_ip_type ip,
	}
	rule_hdr->u.hdr.pipe_dest_idx = pipe_idx;
	rule_hdr->u.hdr.system = !ipa_ctx->hdr_tbl_lcl;

	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EPERM;
		}
	}
	if (entry->hdr) {
		if (entry->hdr->cookie == IPA_HDR_COOKIE) {
			rule_hdr->u.hdr.hdr_offset =
@@ -140,6 +153,8 @@ int __ipa_generate_rt_hw_rule_v2_5(enum ipa_ip_type ip,
	u32 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE/4];
	u8 *start;
	int pipe_idx;
	struct ipa_hdr_entry *hdr_entry;
	struct ipa_hdr_proc_ctx_entry *hdr_proc_entry;

	if (buf == NULL) {
		memset(tmp, 0, IPA_RT_FLT_HW_RULE_BUF_SIZE);
@@ -162,6 +177,24 @@ int __ipa_generate_rt_hw_rule_v2_5(enum ipa_ip_type ip,
		return -EPERM;
	}
	rule_hdr->u.hdr_v2_5.pipe_dest_idx = pipe_idx;
	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EPERM;
		}
	} else if (entry->proc_ctx) {
		hdr_proc_entry = ipa_id_find(entry->rule.hdr_proc_ctx_hdl);
		if (!hdr_proc_entry ||
			hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
			IPAERR_RL("Proc header entry already deleted\n");
			return -EPERM;
		}
	}
	if (entry->proc_ctx || (entry->hdr && entry->hdr->is_hdr_proc_ctx)) {
		struct ipa_hdr_proc_ctx_entry *proc_ctx;

@@ -1130,6 +1163,8 @@ int __ipa_del_rt_rule(u32 rule_hdl)
{
	struct ipa_rt_entry *entry;
	int id;
	struct ipa_hdr_entry *hdr_entry;
	struct ipa_hdr_proc_ctx_entry *hdr_proc_entry;

	entry = ipa_id_find(rule_hdl);

@@ -1151,6 +1186,24 @@ int __ipa_del_rt_rule(u32 rule_hdl)
			return -EINVAL;
		}
	}
	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EINVAL;
		}
	} else if (entry->proc_ctx) {
		hdr_proc_entry = ipa_id_find(entry->rule.hdr_proc_ctx_hdl);
		if (!hdr_proc_entry ||
			hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
			IPAERR_RL("Proc header entry already deleted\n");
			return -EINVAL;
		}
	}

	if (entry->hdr)
		__ipa_release_hdr(entry->hdr->id);
@@ -1463,6 +1516,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
{
	struct ipa_rt_entry *entry;
	struct ipa_hdr_entry *hdr = NULL;
	struct ipa_hdr_entry *hdr_entry;

	if (rtrule->rule.hdr_hdl) {
		hdr = ipa_id_find(rtrule->rule.hdr_hdl);
@@ -1483,6 +1537,17 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
		goto error;
	}

	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EPERM;
		}
	}
	if (entry->hdr)
		entry->hdr->ref_cnt--;

+63 −1
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
	struct ipa3_rt_entry *entry, u8 *buf)
{
	struct ipahal_rt_rule_gen_params gen_params;
	struct ipa3_hdr_entry *hdr_entry;
	struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
	int res = 0;

	memset(&gen_params, 0, sizeof(gen_params));
@@ -69,6 +71,25 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
		return -EPERM;
	}

	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EPERM;
		}
	} else if (entry->proc_ctx) {
		hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
		if (!hdr_proc_entry ||
			hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
			IPAERR_RL("Proc header entry already deleted\n");
			return -EPERM;
		}
	}

	if (entry->proc_ctx || (entry->hdr && entry->hdr->is_hdr_proc_ctx)) {
		struct ipa3_hdr_proc_ctx_entry *proc_ctx;
		proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx;
@@ -1268,6 +1289,8 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
{
	struct ipa3_rt_entry *entry;
	int id;
	struct ipa3_hdr_entry *hdr_entry;
	struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;

	entry = ipa3_id_find(rule_hdl);

@@ -1290,6 +1313,25 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
		}
	}

	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EINVAL;
		}
	} else if (entry->proc_ctx) {
		hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
		if (!hdr_proc_entry ||
			hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
			IPAERR_RL("Proc header entry already deleted\n");
			return -EINVAL;
		}
	}

	if (entry->hdr)
		__ipa3_release_hdr(entry->hdr->id);
	else if (entry->proc_ctx)
@@ -1609,7 +1651,8 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
	struct ipa3_rt_entry *entry;
	struct ipa3_hdr_entry *hdr = NULL;
	struct ipa3_hdr_proc_ctx_entry *proc_ctx = NULL;

	struct ipa3_hdr_entry *hdr_entry;
	struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
	if (rtrule->rule.hdr_hdl) {
		hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
		if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
@@ -1636,6 +1679,25 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
		goto error;
	}

	/* Adding check to confirm still
	 * header entry present in header table or not
	 */

	if (entry->hdr) {
		hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
		if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
			IPAERR_RL("Header entry already deleted\n");
			return -EPERM;
		}
	} else if (entry->proc_ctx) {
		hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
		if (!hdr_proc_entry ||
			hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
			IPAERR_RL("Proc header entry already deleted\n");
			return -EPERM;
		}
	}

	if (entry->hdr)
		entry->hdr->ref_cnt--;
	if (entry->proc_ctx)