msm: ipa: add additional checks to prevent use-after free errors
Adding a function to check for dangling pointer using IPA IDR structure to avoid use after free error. Change-Id: I0bd3d733bf10403366abc643f89c3e5c5e6228e9 Acked-by: Suhas Mallesh <smallesh@qti.qualcomm.com> Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
This commit is contained in:
parent
c652adc152
commit
03879f74a7
4 changed files with 31 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* 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
|
* 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
|
* 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));
|
memset(&gen_params, 0, sizeof(gen_params));
|
||||||
|
|
||||||
gen_params.ipt = 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;
|
gen_params.rt_tbl_idx = entry->rt_tbl->idx;
|
||||||
else
|
else
|
||||||
gen_params.rt_tbl_idx = entry->rule.rt_tbl_idx;
|
gen_params.rt_tbl_idx = entry->rule.rt_tbl_idx;
|
||||||
|
@ -1402,7 +1402,9 @@ int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only)
|
||||||
entry->ipacm_installed) {
|
entry->ipacm_installed) {
|
||||||
list_del(&entry->link);
|
list_del(&entry->link);
|
||||||
entry->tbl->rule_cnt--;
|
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--;
|
entry->rt_tbl->ref_cnt--;
|
||||||
/* if rule id was allocated from idr, remove */
|
/* if rule id was allocated from idr, remove */
|
||||||
rule_id = entry->rule_id;
|
rule_id = entry->rule_id;
|
||||||
|
|
|
@ -2125,5 +2125,6 @@ struct dentry *ipa_debugfs_get_root(void);
|
||||||
bool ipa3_is_msm_device(void);
|
bool ipa3_is_msm_device(void);
|
||||||
struct device *ipa3_get_pdev(void);
|
struct device *ipa3_get_pdev(void);
|
||||||
int ipa3_allocate_dma_task_for_gsi(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);
|
void ipa3_free_dma_task_for_gsi(void);
|
||||||
#endif /* _IPA3_I_H_ */
|
#endif /* _IPA3_I_H_ */
|
||||||
|
|
|
@ -94,6 +94,7 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
|
||||||
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
|
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
|
||||||
proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx;
|
proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx;
|
||||||
if ((proc_ctx == NULL) ||
|
if ((proc_ctx == NULL) ||
|
||||||
|
ipa3_check_idr_if_freed(proc_ctx) ||
|
||||||
(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
|
(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
|
||||||
gen_params.hdr_type = IPAHAL_RT_RULE_HDR_NONE;
|
gen_params.hdr_type = IPAHAL_RT_RULE_HDR_NONE;
|
||||||
gen_params.hdr_ofst = 0;
|
gen_params.hdr_ofst = 0;
|
||||||
|
@ -731,7 +732,8 @@ struct ipa3_rt_tbl *__ipa3_find_rt_tbl(enum ipa_ip_type ip, const char *name)
|
||||||
|
|
||||||
set = &ipa3_ctx->rt_tbl_set[ip];
|
set = &ipa3_ctx->rt_tbl_set[ip];
|
||||||
list_for_each_entry(entry, &set->head_rt_tbl_list, link) {
|
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;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1366,7 +1368,8 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
|
||||||
|
|
||||||
if (entry->hdr)
|
if (entry->hdr)
|
||||||
__ipa3_release_hdr(entry->hdr->id);
|
__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);
|
__ipa3_release_hdr_proc_ctx(entry->proc_ctx->id);
|
||||||
list_del(&entry->link);
|
list_del(&entry->link);
|
||||||
entry->tbl->rule_cnt--;
|
entry->tbl->rule_cnt--;
|
||||||
|
@ -1567,7 +1570,9 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
|
||||||
tbl->rule_cnt--;
|
tbl->rule_cnt--;
|
||||||
if (rule->hdr)
|
if (rule->hdr)
|
||||||
__ipa3_release_hdr(rule->hdr->id);
|
__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(
|
__ipa3_release_hdr_proc_ctx(
|
||||||
rule->proc_ctx->id);
|
rule->proc_ctx->id);
|
||||||
rule->cookie = 0;
|
rule->cookie = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* 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
|
* 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
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -3865,3 +3865,19 @@ struct device *ipa3_get_pdev(void)
|
||||||
|
|
||||||
return ipa3_ctx->pdev;
|
return ipa3_ctx->pdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue