From da87131740351b833f17f05dfa859977bc1e7684 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Tue, 29 Nov 2016 08:19:13 -0800 Subject: qcacld-2.0: Avoid overflow of "significant change" params The wlan driver supports the following vendor command: QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE This command supplies a "number of APs" attribute as well as a list of per-AP attributes. However there is no validation that the number of APs provided won't overflow the destination buffer. In addition there is no validation that the number of APs actually provided matches the number of APs expected. To address these issues: * Verify that the expected number of APs doesn't exceed the maximum allowed number of APs * Verify that the actual number of APs supplied doesn't exceed the expected number of APs * Only process the actual number of supplied APs if it is less than the expected number of APs. Change-Id: I0513ffbc4a38f1d7ddbc0815d3618fc9a2ea4f77 CRs-Fixed: 1095009 --- CORE/HDD/src/wlan_hdd_cfg80211.c | 16 ++++++++++++++++ CORE/SERVICES/WMA/wma.c | 6 +++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 800d123..d91859f 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -3342,6 +3342,11 @@ static int __wlan_hdd_cfg80211_extscan_set_significant_change( } pReqMsg->numAp = nla_get_u32( tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]); + if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) { + hddLog(LOGE, FL("Number of AP %u exceeds max %u"), + pReqMsg->numAp, WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS); + goto fail; + } pReqMsg->sessionId = pAdapter->sessionId; hddLog(LOG1, FL("Number of AP %d Session Id %d"), pReqMsg->numAp, @@ -3350,6 +3355,12 @@ static int __wlan_hdd_cfg80211_extscan_set_significant_change( i = 0; nla_for_each_nested(apTh, tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) { + + if (i == pReqMsg->numAp) { + hddLog(LOGW, FL("Ignoring excess AP")); + break; + } + if (nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, nla_data(apTh), nla_len(apTh), @@ -3389,6 +3400,11 @@ static int __wlan_hdd_cfg80211_extscan_set_significant_change( i++; } + if (i < pReqMsg->numAp) { + hddLog(LOGW, FL("Number of AP %u less than expected %u"), + i, pReqMsg->numAp); + pReqMsg->numAp = i; + } context = &pHddCtx->ext_scan_context; spin_lock(&hdd_context_lock); diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 0f803d4..2cf66bf 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -28926,9 +28926,9 @@ VOS_STATUS wma_get_buf_extscan_change_monitor_cmd(tp_wma_handle wma_handle, int numap = psigchange->numAp; tSirAPThresholdParam *src_ap = psigchange->ap; - if (!numap) { - WMA_LOGE("%s: Invalid number of bssid's", - __func__); + if ((numap <= 0) || (numap > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS)) { + WMA_LOGE("%s: Invalid number of APs: %d", + __func__, numap); return VOS_STATUS_E_INVAL; } len += WMI_TLV_HDR_SIZE; -- cgit v1.1