From 8a4ffccc02a2d462966317e9293f3b38462c6986 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Thu, 30 Jan 2020 23:10:51 +0530 Subject: [PATCH] qcacld-3.0: Replace stack alloc for struct tPmkidCacheInfo with heap alloc Currently the strucutre tPmkidCacheInfo is allocated in stack and used during pmksa operations. This structure takes up ~100 bytes of memory. This will cause stack corruption in low memory devices. Move allocations of structure tPmkidCacheInfo to heap. Change-Id: Ibcf44bc331a9ef94499071af1899914edd75b3cf CRs-Fixed: 2616488 --- core/hdd/src/wlan_hdd_cfg80211.c | 53 ++++++++++++++++++++------------ core/sme/src/csr/csr_api_roam.c | 52 +++++++++++++++++++++---------- core/sme/src/csr/csr_util.c | 22 +++++++++---- 3 files changed, 85 insertions(+), 42 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 8ef2167119ae..d4dcb4487863 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -21270,7 +21270,7 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, mac_handle_t mac_handle; QDF_STATUS result = QDF_STATUS_SUCCESS; int status; - tPmkidCacheInfo pmk_cache; + tPmkidCacheInfo *pmk_cache; hdd_enter(); @@ -21301,11 +21301,13 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, if (0 != status) return status; + pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache)); + if (!pmk_cache) + return -ENOMEM; + mac_handle = hdd_ctx->mac_handle; - qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); - - hdd_fill_pmksa_info(adapter, &pmk_cache, pmksa, false); + hdd_fill_pmksa_info(adapter, pmk_cache, pmksa, false); /* * Add to the PMKSA Cache in CSR @@ -21314,16 +21316,18 @@ static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, * 2. pmk * 3. bssid or cache identifier */ - result = wlan_hdd_set_pmksa_cache(adapter, &pmk_cache); + result = wlan_hdd_set_pmksa_cache(adapter, pmk_cache); qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SET_PMKSA, adapter->vdev_id, result); sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, - &pmk_cache, true); + pmk_cache, true); - qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); + qdf_mem_zero(pmk_cache, sizeof(pmk_cache)); + + qdf_mem_free(pmk_cache); hdd_exit(); return QDF_IS_STATUS_SUCCESS(result) ? 0 : -EINVAL; @@ -21371,7 +21375,7 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); mac_handle_t mac_handle; int status = 0; - tPmkidCacheInfo pmk_cache; + tPmkidCacheInfo *pmk_cache; hdd_enter(); @@ -21396,29 +21400,33 @@ static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, if (0 != status) return status; + pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache)); + if (!pmk_cache) + return -ENOMEM; + mac_handle = hdd_ctx->mac_handle; qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_DEL_PMKSA, adapter->vdev_id, 0); - qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); - - hdd_fill_pmksa_info(adapter, &pmk_cache, pmksa, true); + hdd_fill_pmksa_info(adapter, pmk_cache, pmksa, true); /* Delete the PMKID CSR cache */ if (QDF_STATUS_SUCCESS != - wlan_hdd_del_pmksa_cache(adapter, &pmk_cache)) { + wlan_hdd_del_pmksa_cache(adapter, pmk_cache)) { hdd_err("Failed to delete PMKSA for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(pmksa->bssid)); status = -EINVAL; } - sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, &pmk_cache, + sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, pmk_cache, false); - qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); + qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); + qdf_mem_free(pmk_cache); hdd_exit(); + return status; } @@ -22854,18 +22862,25 @@ wlan_hdd_extauth_cache_pmkid(struct hdd_adapter *adapter, mac_handle_t mac_handle, struct cfg80211_external_auth_params *params) { - tPmkidCacheInfo pmk_cache; + tPmkidCacheInfo *pmk_cache; QDF_STATUS result; + if (params->pmkid) { - qdf_mem_zero(&pmk_cache, sizeof(pmk_cache)); - qdf_mem_copy(pmk_cache.BSSID.bytes, params->bssid, + pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache)); + if (!pmk_cache) + return; + + qdf_mem_copy(pmk_cache->BSSID.bytes, params->bssid, QDF_MAC_ADDR_SIZE); - qdf_mem_copy(pmk_cache.PMKID, params->pmkid, + qdf_mem_copy(pmk_cache->PMKID, params->pmkid, PMKID_LEN); - result = wlan_hdd_set_pmksa_cache(adapter, &pmk_cache); + result = wlan_hdd_set_pmksa_cache(adapter, pmk_cache); if (!QDF_IS_STATUS_SUCCESS(result)) hdd_debug("external_auth: Failed to cache PMKID"); + + qdf_mem_free(pmk_cache); } + } /** diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index e03f25ec964c..0328fd19d432 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -9440,7 +9440,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, mac_handle_t mac_handle = MAC_HANDLE(mac); struct csr_roam_session *session_ptr; struct csr_roam_connectedinfo *prev_connect_info; - tPmkidCacheInfo pmksa_entry; + tPmkidCacheInfo *pmksa_entry; uint32_t len = 0, roamId = 0, reason_code = 0; bool is_dis_pending; @@ -9520,13 +9520,18 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * AP. */ if (reason_code == eSIR_MAC_INVALID_PMKID) { + pmksa_entry = qdf_mem_malloc(sizeof(*pmksa_entry)); + if (!pmksa_entry) + return; + sme_warn("Assoc reject from BSSID:%pM due to invalid PMKID", session_ptr->joinFailStatusCode.bssId); - qdf_mem_copy(&pmksa_entry.BSSID.bytes, + qdf_mem_copy(pmksa_entry->BSSID.bytes, &session_ptr->joinFailStatusCode.bssId, sizeof(tSirMacAddr)); sme_roam_del_pmkid_from_cache(mac_handle, session_ptr->vdev_id, - &pmksa_entry, false); + pmksa_entry, false); + qdf_mem_free(pmksa_entry); } /* If Join fails while Handoff is in progress, indicate @@ -14969,14 +14974,21 @@ static void csr_update_fils_connection_info(struct csr_roam_profile *profile, static void csr_update_sae_config(struct join_req *csr_join_req, struct mac_context *mac, struct csr_roam_session *session) { - tPmkidCacheInfo pmkid_cache; + tPmkidCacheInfo *pmkid_cache; uint32_t index; - qdf_mem_copy(pmkid_cache.BSSID.bytes, - csr_join_req->bssDescription.bssId, QDF_MAC_ADDR_SIZE); + pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); + if (!pmkid_cache) + return; + + qdf_mem_copy(pmkid_cache->BSSID.bytes, + csr_join_req->bssDescription.bssId, + QDF_MAC_ADDR_SIZE); csr_join_req->sae_pmk_cached = - csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index); + csr_lookup_pmkid_using_bssid(mac, session, pmkid_cache, &index); + + qdf_mem_free(pmkid_cache); if (!csr_join_req->sae_pmk_cached) return; @@ -21081,7 +21093,7 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, sme_QosAssocInfo assoc_info; struct bss_params *add_bss_params; QDF_STATUS status = QDF_STATUS_SUCCESS; - tPmkidCacheInfo pmkid_cache; + tPmkidCacheInfo *pmkid_cache; uint32_t pmkid_index; uint16_t len; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH @@ -21317,27 +21329,33 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx, * Check if a PMK cache exists for the roamed AP and update * it into the session pmk. */ - qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); - qdf_copy_macaddr(&pmkid_cache.BSSID, + pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); + if (!pmkid_cache) { + status = QDF_STATUS_E_NOMEM; + goto end; + } + + qdf_copy_macaddr(&pmkid_cache->BSSID, &session->connectedProfile.bssid); sme_debug("Trying to find PMKID for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes)); + QDF_MAC_ADDR_ARRAY(pmkid_cache->BSSID.bytes)); if (csr_lookup_pmkid_using_bssid(mac_ctx, session, - &pmkid_cache, + pmkid_cache, &pmkid_index)) { - session->pmk_len = pmkid_cache.pmk_len; + session->pmk_len = pmkid_cache->pmk_len; qdf_mem_zero(session->psk_pmk, sizeof(session->psk_pmk)); - qdf_mem_copy(session->psk_pmk, pmkid_cache.pmk, + qdf_mem_copy(session->psk_pmk, pmkid_cache->pmk, session->pmk_len); sme_debug("pmkid found for " QDF_MAC_ADDR_STR " at %d len %d", - QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes), + QDF_MAC_ADDR_ARRAY(pmkid_cache->BSSID.bytes), pmkid_index, (uint32_t)session->pmk_len); } else { sme_debug("PMKID Not found in cache for " QDF_MAC_ADDR_STR, - QDF_MAC_ADDR_ARRAY(pmkid_cache.BSSID.bytes)); + QDF_MAC_ADDR_ARRAY(pmkid_cache->BSSID.bytes)); } - qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); + qdf_mem_zero(pmkid_cache, sizeof(pmkid_cache)); + qdf_mem_free(pmkid_cache); } else { roam_info->fAuthRequired = true; csr_roam_substate_change(mac_ctx, diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index f7f9f219829c..336d0fe37e88 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -2696,22 +2696,32 @@ bool csr_is_pmkid_found_for_peer(struct mac_context *mac, { uint32_t i, index; uint8_t *session_pmkid; - tPmkidCacheInfo pmkid_cache; + tPmkidCacheInfo *pmkid_cache; - qdf_mem_zero(&pmkid_cache, sizeof(pmkid_cache)); - qdf_mem_copy(pmkid_cache.BSSID.bytes, peer_mac_addr, + pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache)); + if (!pmkid_cache) + return false; + + qdf_mem_copy(pmkid_cache->BSSID.bytes, peer_mac_addr, QDF_MAC_ADDR_SIZE); - if (!csr_lookup_pmkid_using_bssid(mac, session, &pmkid_cache, &index)) + if (!csr_lookup_pmkid_using_bssid(mac, session, pmkid_cache, &index)) { + qdf_mem_free(pmkid_cache); return false; - session_pmkid = &pmkid_cache.PMKID[0]; + } + + session_pmkid = pmkid_cache->PMKID; for (i = 0; i < pmkid_count; i++) { if (!qdf_mem_cmp(pmkid + (i * PMKID_LEN), - session_pmkid, PMKID_LEN)) + session_pmkid, PMKID_LEN)) { + qdf_mem_free(pmkid_cache); return true; + } } sme_debug("PMKID in PmkidCacheInfo doesn't match with PMKIDs of peer"); + qdf_mem_free(pmkid_cache); + return false; }