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

Commit 949814d5 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: add additional checks to prevent use-after free errors"

parents 5f1d1a15 7d562e59
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ static int ipa3_generate_flt_hw_rule(enum ipa_ip_type ip,
	}

	gen_params.ipt = ip;
	if (entry->rt_tbl)
	if (entry->rt_tbl && (!ipa3_check_idr_if_freed(entry->rt_tbl)))
		gen_params.rt_tbl_idx = entry->rt_tbl->idx;
	else
		gen_params.rt_tbl_idx = entry->rule.rt_tbl_idx;
@@ -1815,7 +1815,9 @@ int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only)
					entry->ipacm_installed) {
				list_del(&entry->link);
				entry->tbl->rule_cnt--;
				if (entry->rt_tbl)
				if (entry->rt_tbl &&
					(!ipa3_check_idr_if_freed(
						entry->rt_tbl)))
					entry->rt_tbl->ref_cnt--;
				/* if rule id was allocated from idr, remove */
				rule_id = entry->rule_id;
+1 −0
Original line number Diff line number Diff line
@@ -2790,6 +2790,7 @@ int ipa3_alloc_counter_id(struct ipa_ioc_flt_rt_counter_alloc *counter);
void ipa3_counter_remove_hdl(int hdl);
void ipa3_counter_id_remove_all(void);
int ipa3_id_alloc(void *ptr);
bool ipa3_check_idr_if_freed(void *ptr);
void *ipa3_id_find(u32 id);
void ipa3_id_remove(u32 id);
int ipa3_enable_force_clear(u32 request_id, bool throttle_source,
+8 −3
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,

		proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx;
		if ((proc_ctx == NULL) ||
			ipa3_check_idr_if_freed(proc_ctx) ||
			(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
			gen_params.hdr_type = IPAHAL_RT_RULE_HDR_NONE;
			gen_params.hdr_ofst = 0;
@@ -747,7 +748,8 @@ struct ipa3_rt_tbl *__ipa3_find_rt_tbl(enum ipa_ip_type ip, const char *name)

	set = &ipa3_ctx->rt_tbl_set[ip];
	list_for_each_entry(entry, &set->head_rt_tbl_list, link) {
		if (!strcmp(name, entry->name))
		if (!ipa3_check_idr_if_freed(entry) &&
			!strcmp(name, entry->name))
			return entry;
	}

@@ -1747,7 +1749,8 @@ int __ipa3_del_rt_rule(u32 rule_hdl)

	if (entry->hdr)
		__ipa3_release_hdr(entry->hdr->id);
	else if (entry->proc_ctx)
	else if (entry->proc_ctx &&
		(!ipa3_check_idr_if_freed(entry->proc_ctx)))
		__ipa3_release_hdr_proc_ctx(entry->proc_ctx->id);
	list_del(&entry->link);
	entry->tbl->rule_cnt--;
@@ -1948,7 +1951,9 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
				tbl->rule_cnt--;
				if (rule->hdr)
					__ipa3_release_hdr(rule->hdr->id);
				else if (rule->proc_ctx)
				else if (rule->proc_ctx &&
					(!ipa3_check_idr_if_freed(
						rule->proc_ctx)))
					__ipa3_release_hdr_proc_ctx(
						rule->proc_ctx->id);
				rule->cookie = 0;
+16 −0
Original line number Diff line number Diff line
@@ -6274,6 +6274,22 @@ void *ipa3_id_find(u32 id)
	return ptr;
}

bool ipa3_check_idr_if_freed(void *ptr)
{
	int id;
	void *iter_ptr;

	spin_lock(&ipa3_ctx->idr_lock);
	idr_for_each_entry(&ipa3_ctx->ipa_idr, iter_ptr, id) {
		if ((uintptr_t)ptr == (uintptr_t)iter_ptr) {
			spin_unlock(&ipa3_ctx->idr_lock);
			return false;
		}
	}
	spin_unlock(&ipa3_ctx->idr_lock);
	return true;
}

void ipa3_id_remove(u32 id)
{
	spin_lock(&ipa3_ctx->idr_lock);