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

Commit bb1faf31 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: add additional checks to prevent use-after free errors"

parents 5ad49014 a815eaf0
Loading
Loading
Loading
Loading
+5 −3
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
@@ -51,7 +51,7 @@ static int ipa3_generate_flt_hw_rule(enum ipa_ip_type ip,
	memset(&gen_params, 0, sizeof(gen_params));

	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;
@@ -1400,7 +1400,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
@@ -2586,6 +2586,7 @@ void ipa3_enable_dcd(void);
void ipa3_disable_prefetch(enum ipa_client_type client);
int ipa3_alloc_common_event_ring(void);
int ipa3_allocate_dma_task_for_gsi(void);
bool ipa3_check_idr_if_freed(void *ptr);
void ipa3_free_dma_task_for_gsi(void);
int ipa3_set_clock_plan_from_pm(int idx);
void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys);
+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;
@@ -730,7 +731,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;
	}

@@ -1367,7 +1369,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--;
@@ -1568,7 +1571,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
@@ -6272,6 +6272,22 @@ void ipa3_enable_dcd(void)
			&idle_indication_cfg);
}

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_init_imm_cmd_desc(struct ipa3_desc *desc,
	struct ipahal_imm_cmd_pyld *cmd_pyld)
{