From dd14aa897d6fa0205057f79f7a6b4fe4475d7d4b Mon Sep 17 00:00:00 2001 From: Min Liu Date: Mon, 10 Aug 2020 18:32:00 +0800 Subject: [PATCH] qcacld-3.0: Possible OOB read when parsing QoSMapSet IE Fix possible OOB read when converting QoSMapSet IE into some SME structure. Change-Id: I723f54f313339a0063de3f1409f7de250ae159d5 CRs-Fixed: 2751833 --- core/mac/inc/sir_api.h | 7 +-- core/mac/src/cfg/cfgUtil/dot11f.frms | 4 +- core/mac/src/include/dot11f.h | 8 +-- .../mac/src/sys/legacy/src/utils/src/dot11f.c | 14 +++--- .../sys/legacy/src/utils/src/utils_parser.c | 50 +++++++++---------- 5 files changed, 43 insertions(+), 40 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index ca52d2a66fcf..3b09b203d5b4 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -93,7 +93,8 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN]; #define MAX_POWER_DBG_ARGS_SUPPORTED 8 #define QOS_MAP_MAX_EX 21 -#define QOS_MAP_LEN_MIN 16 +#define QOS_MAP_RANGE_NUM 8 +#define QOS_MAP_LEN_MIN (QOS_MAP_RANGE_NUM * 2) #define QOS_MAP_LEN_MAX \ (QOS_MAP_LEN_MIN + 2 * QOS_MAP_MAX_EX) #define NUM_CHAINS_MAX 2 @@ -1573,8 +1574,8 @@ typedef struct sSirAggrQosRsp { struct qos_map_set { uint8_t present; uint8_t num_dscp_exceptions; - uint8_t dscp_exceptions[21][2]; - uint8_t dscp_range[8][2]; + uint8_t dscp_exceptions[QOS_MAP_MAX_EX][2]; + uint8_t dscp_range[QOS_MAP_RANGE_NUM][2]; }; typedef struct sSmeIbssPeerInd { diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms index 8069954dbf9c..a0096303e8eb 100644 --- a/core/mac/src/cfg/cfgUtil/dot11f.frms +++ b/core/mac/src/cfg/cfgUtil/dot11f.frms @@ -156,6 +156,8 @@ const ANI_WDS_INFO_MAX_LENGTH = 64; const SIR_MAC_MAX_NUMBER_OF_RATES = 12; const HT_MAX_SUPPORTED_MCS_SET = 16; const MAX_SUPPORTED_NEIGHBOR_RPT = 15; +const MAX_QOS_DSCP_DATA_LEN = 58; +const QOS_DSCP_RANGE_LEN = 16; ///////////////////////////////////////////////////////////////////////////// // Wi-Fi Protected Setup TLV Identifiers // @@ -2585,7 +2587,7 @@ IE OperatingMode (EID_OPERATING_MODE) IE QosMapSet (EID_QOS_MAP_SET) { - dscp_exceptions[0..60]; + dscp_exceptions[QOS_DSCP_RANGE_LEN..MAX_QOS_DSCP_DATA_LEN]; } CONTAINERIE RICDataDesc diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h index 2c8c515fbd55..810877683cf2 100644 --- a/core/mac/src/include/dot11f.h +++ b/core/mac/src/include/dot11f.h @@ -26,7 +26,7 @@ * * * This file was automatically generated by 'framesc' - * Mon Jun 8 09:41:47 2020 from the following file(s): + * Tue Aug 11 23:34:13 2020 from the following file(s): * * dot11f.frms * @@ -6609,15 +6609,15 @@ uint32_t dot11f_get_packed_ie_QOSCapsStation( typedef struct sDot11fIEQosMapSet { uint8_t present; uint8_t num_dscp_exceptions; - uint8_t dscp_exceptions[60]; + uint8_t dscp_exceptions[58]; } tDot11fIEQosMapSet; #define DOT11F_EID_QOSMAPSET (110) /* N.B. These #defines do *not* include the EID & length */ -#define DOT11F_IE_QOSMAPSET_MIN_LEN (0) +#define DOT11F_IE_QOSMAPSET_MIN_LEN (16) -#define DOT11F_IE_QOSMAPSET_MAX_LEN (60) +#define DOT11F_IE_QOSMAPSET_MAX_LEN (58) #ifdef __cplusplus extern "C" { diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c index df167185e286..b43128bf6ba7 100644 --- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c +++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c @@ -24,7 +24,7 @@ * * * This file was automatically generated by 'framesc' - * Mon Jun 8 09:41:47 2020 from the following file(s): + * Tue Aug 11 23:34:13 2020 from the following file(s): * * dot11f.frms * @@ -6445,7 +6445,7 @@ uint32_t dot11f_unpack_ie_qos_map_set(tpAniSirGlobal pCtx, return DOT11F_DUPLICATE_IE; pDst->present = 1; pDst->num_dscp_exceptions = (uint8_t)(ielen); - if (ielen > 60) { + if (ielen > 58) { pDst->present = 0; return DOT11F_SKIPPED_BAD_IE; } @@ -9763,7 +9763,7 @@ static const tIEDefn IES_AssocRequest[] = { 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, 0, }, { offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, - present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + present), 0, "QosMapSet", 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap", 0, 3, 17, SigIeExtCap, {0, 0, 0, 0, 0}, @@ -9968,7 +9968,7 @@ static const tIEDefn IES_AssocResponse[] = { 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, }, { offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, - present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + present), 0, "QosMapSet", 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fAssocResponse, fils_session), offsetof(tDot11fIEfils_session, present), 0, "fils_session", @@ -11455,7 +11455,7 @@ static const tFFDefn FFS_QosMapConfigure[] = { static const tIEDefn IES_QosMapConfigure[] = { { offsetof(tDot11fQosMapConfigure, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet", - 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 1, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; @@ -11666,7 +11666,7 @@ static const tIEDefn IES_ReAssocRequest[] = { 0, DOT11F_EID_OPERATINGMODE, 0, 0, }, { offsetof(tDot11fReAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet", - 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fReAssocRequest, vendor_vht_ie), offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie", @@ -11810,7 +11810,7 @@ static const tIEDefn IES_ReAssocResponse[] = { 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, 0, }, { offsetof(tDot11fReAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet", - 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, + 0, 18, 60, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, 0, }, { offsetof(tDot11fReAssocResponse, vendor_vht_ie), offsetof(tDot11fIEvendor_vht_ie, present), 0, "vendor_vht_ie", diff --git a/core/mac/src/sys/legacy/src/utils/src/utils_parser.c b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c index 48d342430e83..c4b8cc82ed40 100644 --- a/core/mac/src/sys/legacy/src/utils/src/utils_parser.c +++ b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -650,35 +650,35 @@ void convert_wmm_schedule(struct mac_context *mac, pOld->specInterval = pNew->spec_interval; } -void convert_qos_mapset_frame(struct mac_context *mac, struct qos_map_set *Qos, - tDot11fIEQosMapSet *dot11fIE) +void convert_qos_mapset_frame(struct mac_context *mac, struct qos_map_set *qos, + tDot11fIEQosMapSet *dot11f_ie) { uint8_t i, j = 0; - uint8_t qos_dscp_sz, dot11_dscp_sz; + uint8_t dot11_dscp_exception_sz; - qos_dscp_sz = (sizeof(Qos->dscp_exceptions)/2); - dot11_dscp_sz = sizeof(dot11fIE->dscp_exceptions); - if (dot11fIE->num_dscp_exceptions > QOS_MAP_LEN_MAX) - dot11fIE->num_dscp_exceptions = QOS_MAP_LEN_MAX; - if (dot11fIE->num_dscp_exceptions < QOS_MAP_LEN_MIN) + if (dot11f_ie->num_dscp_exceptions < DOT11F_IE_QOSMAPSET_MIN_LEN || + dot11f_ie->num_dscp_exceptions % 2) { + pe_debug("Invalid num_dscp_exceptions %d", + dot11f_ie->num_dscp_exceptions); return; - Qos->num_dscp_exceptions = - (dot11fIE->num_dscp_exceptions - QOS_MAP_LEN_MIN) / 2; - - for (i = 0; - i < Qos->num_dscp_exceptions && - i < qos_dscp_sz && j < dot11_dscp_sz; - i++) { - Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j]; - j++; - Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j]; - j++; } - for (i = 0; i < 8 && j < dot11_dscp_sz; i++) { - Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j]; - j++; - Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j]; - j++; + + dot11_dscp_exception_sz = dot11f_ie->num_dscp_exceptions - + DOT11F_IE_QOSMAPSET_MIN_LEN; + qos->num_dscp_exceptions = dot11_dscp_exception_sz / 2; + if (qos->num_dscp_exceptions > QOS_MAP_MAX_EX) + qos->num_dscp_exceptions = QOS_MAP_MAX_EX; + + for (i = 0; i < qos->num_dscp_exceptions && + j < dot11_dscp_exception_sz - 1; i++) { + qos->dscp_exceptions[i][0] = dot11f_ie->dscp_exceptions[j++]; + qos->dscp_exceptions[i][1] = dot11f_ie->dscp_exceptions[j++]; + } + + for (i = 0; i < QOS_MAP_RANGE_NUM && + j < dot11f_ie->num_dscp_exceptions - 1; i++) { + qos->dscp_range[i][0] = dot11f_ie->dscp_exceptions[j++]; + qos->dscp_range[i][1] = dot11f_ie->dscp_exceptions[j++]; } }