From 69a76a9f4e633f28d3a66c793e50c6fd60670570 Mon Sep 17 00:00:00 2001 From: Vignesh Viswanathan Date: Mon, 30 Apr 2018 15:14:59 +0530 Subject: [PATCH] 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 --- .../src/sys/legacy/src/utils/src/parser_api.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 6291db0327..ee3412d7d4 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -2330,6 +2330,7 @@ void update_fils_data(struct sir_fils_indication *fils_ind, tDot11fIEfils_indication *fils_indication) { uint8_t *data; + uint8_t remaining_data = fils_indication->num_variable_data; data = fils_indication->variable_data; 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_indication->is_pk_auth_supported; 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; qdf_mem_copy(fils_ind->cache_identifier.identifier, 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 (remaining_data < SIR_HESSID_LEN) { + pe_err("Failed to copy HESSID, Invalid remaining data %d", + remaining_data); + return; + } fils_ind->hessid.is_present = true; qdf_mem_copy(fils_ind->hessid.hessid, data, SIR_HESSID_LEN); data = data + SIR_HESSID_LEN; + remaining_data = remaining_data - SIR_HESSID_LEN; } 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.realm_cnt = fils_indication->realm_identifiers_cnt;