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
This commit is contained in:
Min Liu 2020-08-10 18:32:00 +08:00 • committed by snandini
commit dd14aa897d
5 changed files with 43 additions and 40 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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" {

View file

@ -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",

View file

@ -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++];
}
}