msm: ipa: Fix to slab out of bounds issue
Add changes to verify passed value with in the allocated max array size range or not before accessing structure. Change-Id: If70493e937f6f0bc29bbfe08bf43738bdb4e9cf4 Acked-by: Ashok Vuyyuru <avuyyuru@qti.qualcomm.com> Signed-off-by: Mohammed Javid <mjavid@codeaurora.org>
This commit is contained in:
parent
d803000f57
commit
1e03864e8a
3 changed files with 115 additions and 19 deletions
|
@ -432,6 +432,8 @@ static ssize_t ipa_read_hdr(struct file *file, char __user *ubuf, size_t count,
|
|||
|
||||
list_for_each_entry(entry, &ipa_ctx->hdr_tbl.head_hdr_entry_list,
|
||||
link) {
|
||||
if (entry->cookie != IPA_HDR_COOKIE)
|
||||
continue;
|
||||
nbytes = scnprintf(
|
||||
dbg_buff,
|
||||
IPA_MAX_MSG_LEN,
|
||||
|
@ -606,6 +608,14 @@ static int ipa_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
if (attrib->protocol_eq_present)
|
||||
pr_err("protocol:%d ", attrib->protocol_eq);
|
||||
|
||||
if (attrib->num_ihl_offset_range_16 >
|
||||
IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS) {
|
||||
IPAERR_RL("num_ihl_offset_range_16 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS,
|
||||
attrib->num_ihl_offset_range_16);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_ihl_offset_range_16; i++) {
|
||||
pr_err(
|
||||
"(ihl_ofst_range16: ofst:%u lo:%u hi:%u) ",
|
||||
|
@ -614,6 +624,12 @@ static int ipa_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
attrib->ihl_offset_range_16[i].range_high);
|
||||
}
|
||||
|
||||
if (attrib->num_offset_meq_32 > IPA_IPFLTR_NUM_MEQ_32_EQNS) {
|
||||
IPAERR_RL("num_offset_meq_32 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_MEQ_32_EQNS, attrib->num_offset_meq_32);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_offset_meq_32; i++) {
|
||||
pr_err(
|
||||
"(ofst_meq32: ofst:%u mask:0x%x val:0x%x) ",
|
||||
|
@ -635,6 +651,12 @@ static int ipa_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
attrib->ihl_offset_eq_16.value);
|
||||
}
|
||||
|
||||
if (attrib->num_ihl_offset_meq_32 > IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS) {
|
||||
IPAERR_RL("num_ihl_offset_meq_32 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS, attrib->num_ihl_offset_meq_32);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_ihl_offset_meq_32; i++) {
|
||||
pr_err(
|
||||
"(ihl_ofst_meq32: ofts:%d mask:0x%x val:0x%x) ",
|
||||
|
@ -643,6 +665,12 @@ static int ipa_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
attrib->ihl_offset_meq_32[i].value);
|
||||
}
|
||||
|
||||
if (attrib->num_offset_meq_128 > IPA_IPFLTR_NUM_MEQ_128_EQNS) {
|
||||
IPAERR_RL("num_offset_meq_128 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_MEQ_128_EQNS, attrib->num_offset_meq_128);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_offset_meq_128; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
addr[j] = attrib->offset_meq_128[i].value[j];
|
||||
|
@ -812,11 +840,14 @@ static ssize_t ipa_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
u32 rt_tbl_idx;
|
||||
u32 bitmap;
|
||||
bool eq;
|
||||
int res = 0;
|
||||
|
||||
tbl = &ipa_ctx->glob_flt_tbl[ip];
|
||||
mutex_lock(&ipa_ctx->lock);
|
||||
i = 0;
|
||||
list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE)
|
||||
continue;
|
||||
if (entry->rule.eq_attrib_type) {
|
||||
rt_tbl_idx = entry->rule.rt_tbl_idx;
|
||||
bitmap = entry->rule.eq_attrib.rule_eq_bitmap;
|
||||
|
@ -835,10 +866,14 @@ static ssize_t ipa_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
i, entry->rule.action, rt_tbl_idx);
|
||||
pr_err("attrib_mask:%08x retain_hdr:%d eq:%d ",
|
||||
bitmap, entry->rule.retain_hdr, eq);
|
||||
if (eq)
|
||||
ipa_attrib_dump_eq(
|
||||
if (eq) {
|
||||
res = ipa_attrib_dump_eq(
|
||||
&entry->rule.eq_attrib);
|
||||
else
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
} else
|
||||
ipa_attrib_dump(
|
||||
&entry->rule.attrib, ip);
|
||||
i++;
|
||||
|
@ -848,6 +883,8 @@ static ssize_t ipa_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
tbl = &ipa_ctx->flt_tbl[j][ip];
|
||||
i = 0;
|
||||
list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE)
|
||||
continue;
|
||||
if (entry->rule.eq_attrib_type) {
|
||||
rt_tbl_idx = entry->rule.rt_tbl_idx;
|
||||
bitmap = entry->rule.eq_attrib.rule_eq_bitmap;
|
||||
|
@ -867,18 +904,23 @@ static ssize_t ipa_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
pr_err("attrib_mask:%08x retain_hdr:%d ",
|
||||
bitmap, entry->rule.retain_hdr);
|
||||
pr_err("eq:%d ", eq);
|
||||
if (eq)
|
||||
ipa_attrib_dump_eq(
|
||||
&entry->rule.eq_attrib);
|
||||
else
|
||||
if (eq) {
|
||||
res = ipa_attrib_dump_eq(
|
||||
&entry->rule.eq_attrib);
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
} else
|
||||
ipa_attrib_dump(
|
||||
&entry->rule.attrib, ip);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
mutex_unlock(&ipa_ctx->lock);
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t ipa_read_stats(struct file *file, char __user *ubuf,
|
||||
|
|
|
@ -357,6 +357,8 @@ static ssize_t ipa3_read_hdr(struct file *file, char __user *ubuf, size_t count,
|
|||
|
||||
list_for_each_entry(entry, &ipa3_ctx->hdr_tbl.head_hdr_entry_list,
|
||||
link) {
|
||||
if (entry->cookie != IPA_HDR_COOKIE)
|
||||
continue;
|
||||
nbytes = scnprintf(
|
||||
dbg_buff,
|
||||
IPA_MAX_MSG_LEN,
|
||||
|
@ -540,6 +542,12 @@ static int ipa3_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
if (attrib->tc_eq_present)
|
||||
pr_err("tc:%d ", attrib->tc_eq);
|
||||
|
||||
if (attrib->num_offset_meq_128 > IPA_IPFLTR_NUM_MEQ_128_EQNS) {
|
||||
IPAERR_RL("num_offset_meq_128 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_MEQ_128_EQNS, attrib->num_offset_meq_128);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_offset_meq_128; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
addr[j] = attrib->offset_meq_128[i].value[j];
|
||||
|
@ -551,6 +559,12 @@ static int ipa3_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
mask, addr);
|
||||
}
|
||||
|
||||
if (attrib->num_offset_meq_32 > IPA_IPFLTR_NUM_MEQ_32_EQNS) {
|
||||
IPAERR_RL("num_offset_meq_32 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_MEQ_32_EQNS, attrib->num_offset_meq_32);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_offset_meq_32; i++)
|
||||
pr_err(
|
||||
"(ofst_meq32: ofst:%u mask:0x%x val:0x%x) ",
|
||||
|
@ -558,6 +572,12 @@ static int ipa3_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
attrib->offset_meq_32[i].mask,
|
||||
attrib->offset_meq_32[i].value);
|
||||
|
||||
if (attrib->num_ihl_offset_meq_32 > IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS) {
|
||||
IPAERR_RL("num_ihl_offset_meq_32 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_IHL_MEQ_32_EQNS, attrib->num_ihl_offset_meq_32);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_ihl_offset_meq_32; i++)
|
||||
pr_err(
|
||||
"(ihl_ofst_meq32: ofts:%d mask:0x%x val:0x%x) ",
|
||||
|
@ -572,6 +592,14 @@ static int ipa3_attrib_dump_eq(struct ipa_ipfltri_rule_eq *attrib)
|
|||
attrib->metadata_meq32.mask,
|
||||
attrib->metadata_meq32.value);
|
||||
|
||||
if (attrib->num_ihl_offset_range_16 >
|
||||
IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS) {
|
||||
IPAERR_RL("num_ihl_offset_range_16 Max %d passed value %d\n",
|
||||
IPA_IPFLTR_NUM_IHL_RANGE_16_EQNS,
|
||||
attrib->num_ihl_offset_range_16);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < attrib->num_ihl_offset_range_16; i++)
|
||||
pr_err(
|
||||
"(ihl_ofst_range16: ofst:%u lo:%u hi:%u) ",
|
||||
|
@ -764,7 +792,11 @@ static ssize_t ipa3_read_rt_hw(struct file *file, char __user *ubuf,
|
|||
pr_err("rule_id:%u prio:%u retain_hdr:%u ",
|
||||
rules[rl].id, rules[rl].priority,
|
||||
rules[rl].retain_hdr);
|
||||
ipa3_attrib_dump_eq(&rules[rl].eq_attrib);
|
||||
res = ipa3_attrib_dump_eq(&rules[rl].eq_attrib);
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("=== Routing Table %d = Non-Hashable Rules ===\n", tbl);
|
||||
|
@ -795,7 +827,11 @@ static ssize_t ipa3_read_rt_hw(struct file *file, char __user *ubuf,
|
|||
pr_err("rule_id:%u prio:%u retain_hdr:%u\n",
|
||||
rules[rl].id, rules[rl].priority,
|
||||
rules[rl].retain_hdr);
|
||||
ipa3_attrib_dump_eq(&rules[rl].eq_attrib);
|
||||
res = ipa3_attrib_dump_eq(&rules[rl].eq_attrib);
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
pr_err("\n");
|
||||
}
|
||||
|
@ -869,6 +905,7 @@ static ssize_t ipa3_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
u32 rt_tbl_idx;
|
||||
u32 bitmap;
|
||||
bool eq;
|
||||
int res = 0;
|
||||
|
||||
mutex_lock(&ipa3_ctx->lock);
|
||||
|
||||
|
@ -878,6 +915,8 @@ static ssize_t ipa3_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
tbl = &ipa3_ctx->flt_tbl[j][ip];
|
||||
i = 0;
|
||||
list_for_each_entry(entry, &tbl->head_flt_rule_list, link) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE)
|
||||
continue;
|
||||
if (entry->rule.eq_attrib_type) {
|
||||
rt_tbl_idx = entry->rule.rt_tbl_idx;
|
||||
bitmap = entry->rule.eq_attrib.rule_eq_bitmap;
|
||||
|
@ -899,18 +938,23 @@ static ssize_t ipa3_read_flt(struct file *file, char __user *ubuf, size_t count,
|
|||
pr_err("hashable:%u rule_id:%u max_prio:%u prio:%u ",
|
||||
entry->rule.hashable, entry->rule_id,
|
||||
entry->rule.max_prio, entry->prio);
|
||||
if (eq)
|
||||
ipa3_attrib_dump_eq(
|
||||
if (eq) {
|
||||
res = ipa3_attrib_dump_eq(
|
||||
&entry->rule.eq_attrib);
|
||||
else
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
} else
|
||||
ipa3_attrib_dump(
|
||||
&entry->rule.attrib, ip);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
mutex_unlock(&ipa3_ctx->lock);
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t ipa3_read_flt_hw(struct file *file, char __user *ubuf,
|
||||
|
@ -961,7 +1005,11 @@ static ssize_t ipa3_read_flt_hw(struct file *file, char __user *ubuf,
|
|||
bitmap, rules[rl].rule.retain_hdr);
|
||||
pr_err("rule_id:%u prio:%u ",
|
||||
rules[rl].id, rules[rl].priority);
|
||||
ipa3_attrib_dump_eq(&rules[rl].rule.eq_attrib);
|
||||
res = ipa3_attrib_dump_eq(&rules[rl].rule.eq_attrib);
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
pr_err("=== Filtering Table ep:%d = Non-Hashable Rules ===\n",
|
||||
|
@ -985,7 +1033,11 @@ static ssize_t ipa3_read_flt_hw(struct file *file, char __user *ubuf,
|
|||
bitmap, rules[rl].rule.retain_hdr);
|
||||
pr_err("rule_id:%u prio:%u ",
|
||||
rules[rl].id, rules[rl].priority);
|
||||
ipa3_attrib_dump_eq(&rules[rl].rule.eq_attrib);
|
||||
res = ipa3_attrib_dump_eq(&rules[rl].rule.eq_attrib);
|
||||
if (res) {
|
||||
IPAERR_RL("failed read attrib eq\n");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
pr_err("\n");
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -61,8 +61,10 @@ static int ipa3_generate_flt_hw_rule(enum ipa_ip_type ip,
|
|||
gen_params.rule = (const struct ipa_flt_rule *)&entry->rule;
|
||||
|
||||
res = ipahal_flt_generate_hw_rule(&gen_params, &entry->hw_len, buf);
|
||||
if (res)
|
||||
IPAERR("failed to generate flt h/w rule\n");
|
||||
if (res) {
|
||||
IPAERR_RL("failed to generate flt h/w rule\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue