From ba0f55e44b5a89bc864f50c8439d6b9af0309443 Mon Sep 17 00:00:00 2001 From: Jyoti Kumari Date: Fri, 29 Jan 2021 12:59:07 +0530 Subject: [PATCH 1/2] qcacld-3.0: Fix integer underflow in assoc response frame In func aead_decrypt_assoc_rsp(), it calls find_ie_data_after_fils_session_ie() to find IE pointer after FILS session IE from the frame payload. There is possibility of integer underflow if frame payload length is less than FIXED_PARAM_OFFSET_ASSOC_RSP which may increase value of buf_len variable in find_ie_data_after_fils_session_ie() and cause OOB during parsing process. Validate frame payload length with FIXED_PARAM_OFFSET_ASSOC_RSP, if it is less then return failure. Change-Id: I78fbcfeaa1058fcf2a6fe47cd5c26390b54974af CRs-Fixed: 2859024 --- core/mac/src/pe/lim/lim_process_fils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/mac/src/pe/lim/lim_process_fils.c b/core/mac/src/pe/lim/lim_process_fils.c index 59fde6851252..99c30eefdfc8 100644 --- a/core/mac/src/pe/lim/lim_process_fils.c +++ b/core/mac/src/pe/lim/lim_process_fils.c @@ -2238,6 +2238,11 @@ QDF_STATUS aead_decrypt_assoc_rsp(tpAniSirGlobal mac_ctx, uint8_t *fils_ies; struct pe_fils_session *fils_info = session->fils_info; + if (*n_frame < FIXED_PARAM_OFFSET_ASSOC_RSP) { + pe_debug("payload len is less than ASSOC RES offset"); + return QDF_STATUS_E_FAILURE; + } + status = find_ie_data_after_fils_session_ie(mac_ctx, p_frame + FIXED_PARAM_OFFSET_ASSOC_RSP, ((*n_frame) - From 4cc2c33231a8446bd31083e396149410c6270ee3 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Mon, 25 Jan 2021 16:16:39 +0530 Subject: [PATCH 2/2] qcacld-3.0: Possible OOB read when parsing FT IE FTIE buffer carries multiple FT subelements (like R1KH-ID, R0KH-ID, GTK, IGTK, etc). Total FTIE buffer len = Number of FT subelements * (Subelement ID (1 bytes) + lenght (1 bytes) + data length). Currently, Host checks only the minimum length for FTIE buffer while filling each FT subelements. This leads to OOB if the remaining length of FTIE length buffer less than the length of an FT subelement. Before filling each subelement into FTIE buffer, add a check to validate subelement length against remaining FTIE length Change-Id: I5d6f4a59eef591d3a2da9f2403738d1fdd1a88b2 CRs-Fixed: 2857084 --- .../src/sys/legacy/src/utils/src/parser_api.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) 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 72e4c43930aa..6010c4e05594 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 @@ -2979,7 +2979,7 @@ QDF_STATUS wlan_parse_ftie_sha384(uint8_t *frame, uint32_t frame_len, struct sSirAssocRsp *assoc_rsp) { const uint8_t *ie, *ie_end, *pos; - uint8_t ie_len; + uint8_t ie_len, remaining_ie_len; struct wlan_sha384_ftinfo_subelem *ft_subelem; ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_FTINFO, frame, frame_len); @@ -2998,12 +2998,13 @@ QDF_STATUS wlan_parse_ftie_sha384(uint8_t *frame, uint32_t frame_len, pe_err("Invalid FTIE len:%d", ie_len); return QDF_STATUS_E_FAILURE; } - + remaining_ie_len = ie_len; pos = ie + 2; qdf_mem_copy(&assoc_rsp->sha384_ft_info, pos, sizeof(struct wlan_sha384_ftinfo)); ie_end = ie + ie_len; pos += sizeof(struct wlan_sha384_ftinfo); + remaining_ie_len -= sizeof(struct wlan_sha384_ftinfo); ft_subelem = &assoc_rsp->sha384_ft_subelem; qdf_mem_zero(ft_subelem, sizeof(*ft_subelem)); @@ -3012,11 +3013,20 @@ QDF_STATUS wlan_parse_ftie_sha384(uint8_t *frame, uint32_t frame_len, id = *pos++; len = *pos++; - if (len < 1) { + /* Subtract data length(len) + 1 bytes for + * Subelement ID + 1 bytes for length from + * remaining FTIE buffer len (ie_len). + * Subelement Parameter(s) field : + * Subelement ID Length Data + * Octets: 1 1 variable + */ + if (len < 1 || remaining_ie_len < (len + 2)) { pe_err("Invalid FT subelem length"); return QDF_STATUS_E_FAILURE; } + remaining_ie_len -= (len + 2); + switch (id) { case FTIE_SUBELEM_R1KH_ID: if (len != FTIE_R1KH_LEN) {