From 61a5cdb9adc96645583f528ac923e6e59f3abbcb Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Wed, 9 Nov 2016 11:22:57 -0800 Subject: qcacld-2.0: Avoid overflow of EXTSCAN bucket list Currently when processing an EXTSCAN vendor command the "num buckets" attribute is limit checked and if it exceeds a MAX value then a warning message is issued. But beyond that the "num buckets" attribute is not used. Instead when the buckets are actually parsed the number of buckets is calculated dynamically based upon the number of attributes present in the request. Unfortunately when the bucket attributes are parsed there is no check to make sure the number of buckets processed does not exceed the MAX value, and as a result a buffer overflow can occur. Address this issue by aborting the bucket parsing once the expected number of records have been parsed. Change-Id: Ic260dd65dc99118afbb8042d102acb5b26d1e123 CRs-Fixed: 1087797 --- CORE/HDD/src/wlan_hdd_cfg80211.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index f488edc..ce8043d 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -3531,6 +3531,7 @@ static int hdd_extscan_start_fill_bucket_channel_spec( int rem1, rem2; eHalStatus status; uint8_t bktIndex, j, numChannels, total_channels = 0; + uint32_t expected_buckets; uint32_t chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; uint32_t min_dwell_time_active_bucket = @@ -3542,7 +3543,6 @@ static int hdd_extscan_start_fill_bucket_channel_spec( uint32_t max_dwell_time_passive_bucket = pHddCtx->cfg_ini->extscan_passive_max_chn_time; - bktIndex = 0; pReqMsg->min_dwell_time_active = pReqMsg->max_dwell_time_active = pHddCtx->cfg_ini->extscan_active_max_chn_time; @@ -3550,10 +3550,19 @@ static int hdd_extscan_start_fill_bucket_channel_spec( pReqMsg->min_dwell_time_passive = pReqMsg->max_dwell_time_passive = pHddCtx->cfg_ini->extscan_passive_max_chn_time; + + expected_buckets = pReqMsg->numBuckets; pReqMsg->numBuckets = 0; + bktIndex = 0; nla_for_each_nested(buckets, tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) { + + if (bktIndex >= expected_buckets) { + hddLog(LOGW, FL("ignoring excess buckets")); + break; + } + if (nla_parse(bucket, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, nla_data(buckets), nla_len(buckets), NULL)) { @@ -4055,8 +4064,10 @@ static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy, hddLog(LOGW, FL("Exceeded MAX number of buckets: %d"), WLAN_EXTSCAN_MAX_BUCKETS); + num_buckets = WLAN_EXTSCAN_MAX_BUCKETS; } hddLog(LOG1, FL("Input: Number of Buckets %d"), num_buckets); + pReqMsg->numBuckets = num_buckets; /* This is optional attribute, if not present set it to 0 */ if (!tb[PARAM_CONFIG_FLAGS]) -- cgit v1.1