qcacld-3.0: Add sanity check variable_data len in update_fils_data
In function update_fils_data, fils_indication->num_variable_data is the actual length of the data present in the array variable_data. While accessing variable_data array to copy cache identifier, HESSID and realm identifiers, the length of the array is not checked and could lead to OOB access. Add check to validate remaining data length in variable_data array before accessing it to copy various fields. Change-Id: Ifc1f5d55964bcd7fdcc2676ea9c2afede0fe6803 CRs-Fixed: 2231767
This commit is contained in:

committed by
nshrivas

parent
e5d8787b0a
commit
69a76a9f4e
@@ -2330,6 +2330,7 @@ void update_fils_data(struct sir_fils_indication *fils_ind,
|
|||||||
tDot11fIEfils_indication *fils_indication)
|
tDot11fIEfils_indication *fils_indication)
|
||||||
{
|
{
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
uint8_t remaining_data = fils_indication->num_variable_data;
|
||||||
|
|
||||||
data = fils_indication->variable_data;
|
data = fils_indication->variable_data;
|
||||||
fils_ind->is_present = true;
|
fils_ind->is_present = true;
|
||||||
@@ -2342,18 +2343,37 @@ void update_fils_data(struct sir_fils_indication *fils_ind,
|
|||||||
fils_ind->is_pk_auth_supported =
|
fils_ind->is_pk_auth_supported =
|
||||||
fils_indication->is_pk_auth_supported;
|
fils_indication->is_pk_auth_supported;
|
||||||
if (fils_indication->is_cache_id_present) {
|
if (fils_indication->is_cache_id_present) {
|
||||||
|
if (remaining_data < SIR_CACHE_IDENTIFIER_LEN) {
|
||||||
|
pe_err("Failed to copy Cache Identifier, Invalid remaining data %d",
|
||||||
|
remaining_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
fils_ind->cache_identifier.is_present = true;
|
fils_ind->cache_identifier.is_present = true;
|
||||||
qdf_mem_copy(fils_ind->cache_identifier.identifier,
|
qdf_mem_copy(fils_ind->cache_identifier.identifier,
|
||||||
data, SIR_CACHE_IDENTIFIER_LEN);
|
data, SIR_CACHE_IDENTIFIER_LEN);
|
||||||
data = data + SIR_CACHE_IDENTIFIER_LEN;
|
data = data + SIR_CACHE_IDENTIFIER_LEN;
|
||||||
|
remaining_data = remaining_data - SIR_CACHE_IDENTIFIER_LEN;
|
||||||
}
|
}
|
||||||
if (fils_indication->is_hessid_present) {
|
if (fils_indication->is_hessid_present) {
|
||||||
|
if (remaining_data < SIR_HESSID_LEN) {
|
||||||
|
pe_err("Failed to copy HESSID, Invalid remaining data %d",
|
||||||
|
remaining_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
fils_ind->hessid.is_present = true;
|
fils_ind->hessid.is_present = true;
|
||||||
qdf_mem_copy(fils_ind->hessid.hessid,
|
qdf_mem_copy(fils_ind->hessid.hessid,
|
||||||
data, SIR_HESSID_LEN);
|
data, SIR_HESSID_LEN);
|
||||||
data = data + SIR_HESSID_LEN;
|
data = data + SIR_HESSID_LEN;
|
||||||
|
remaining_data = remaining_data - SIR_HESSID_LEN;
|
||||||
}
|
}
|
||||||
if (fils_indication->realm_identifiers_cnt) {
|
if (fils_indication->realm_identifiers_cnt) {
|
||||||
|
if (remaining_data < (fils_indication->realm_identifiers_cnt *
|
||||||
|
SIR_REALM_LEN)) {
|
||||||
|
pe_err("Failed to copy Realm Identifier, Invalid remaining data %d realm_cnt %d",
|
||||||
|
remaining_data,
|
||||||
|
fils_indication->realm_identifiers_cnt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
fils_ind->realm_identifier.is_present = true;
|
fils_ind->realm_identifier.is_present = true;
|
||||||
fils_ind->realm_identifier.realm_cnt =
|
fils_ind->realm_identifier.realm_cnt =
|
||||||
fils_indication->realm_identifiers_cnt;
|
fils_indication->realm_identifiers_cnt;
|
||||||
|
Reference in New Issue
Block a user