From 7a7799b04a31cce0dfecea0faae547953b55cbba Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Tue, 21 Jan 2020 10:30:28 +0530 Subject: [PATCH] qcacld-3.0: Fix pmfSaQueryTimer timer leak In case of PMF connection the sta_ds is memset to 0 in case of SA query timeout whithout deleting pmfSaQueryTimer. Also in lim_update_sta_ds pmfSaQueryTimer is created without any check if its already created and thus may lead to overwrite of the previous timer. Thus destroy the pmfSaQueryTimer before memset sta_ds to 0 and before creating it in lim_update_sta_ds. Also use peer deletion is in progress in lim_process_assoc_req_sta_ctx to check if STA is in proper state and assoc can be handled. Change-Id: I63a701c1bd4324c6fce62338df80d0911cc9b703 CRs-Fixed: 2606900 --- .../src/pe/lim/lim_process_assoc_req_frame.c | 146 ++++++++++-------- .../sys/legacy/src/platform/src/sys_wrapper.c | 4 +- 2 files changed, 87 insertions(+), 63 deletions(-) diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index febdd87aa907..0968e9921736 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -1197,6 +1197,36 @@ static bool lim_process_assoc_req_no_sta_ctx(struct mac_context *mac_ctx, return true; } +#ifdef WLAN_DEBUG +static inline void +lim_update_assoc_drop_count(struct mac_context *mac_ctx, uint8_t sub_type) +{ + if (sub_type == LIM_ASSOC) + mac_ctx->lim.gLimNumAssocReqDropInvldState++; + else + mac_ctx->lim.gLimNumReassocReqDropInvldState++; +} +#else +static inline void +lim_update_assoc_drop_count(struct mac_context *mac_ctx, uint8_t sub_type) {} +#endif + +#ifdef WLAN_FEATURE_11W +static inline void +lim_delete_pmf_query_timer(tpDphHashNode sta_ds) +{ + if (!sta_ds->rmfEnabled) + return; + + if (tx_timer_running(&sta_ds->pmfSaQueryTimer)) + tx_timer_deactivate(&sta_ds->pmfSaQueryTimer); + tx_timer_delete(&sta_ds->pmfSaQueryTimer); +} +#else +static inline void +lim_delete_pmf_query_timer(tpDphHashNode sta_ds) {} +#endif + /** * lim_process_assoc_req_sta_ctx() - process assoc req for sta context present * @mac_ctx: pointer to Global MAC structure @@ -1221,29 +1251,16 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx, tpDphHashNode sta_ds, uint16_t peer_idx, tAniAuthType *auth_type, uint8_t *update_ctx) { - /* STA context does exist for this STA */ - if (sta_ds->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) { - /* - * Requesting STA is in some 'transient' state? Ignore the - * Re/Assoc Req frame by incrementing debug counter & logging - * error. - */ - if (sub_type == LIM_ASSOC) { -#ifdef WLAN_DEBUG - mac_ctx->lim.gLimNumAssocReqDropInvldState++; -#endif - pe_debug("received Assoc req in state: %X from", - sta_ds->mlmStaContext.mlmState); - } else { -#ifdef WLAN_DEBUG - mac_ctx->lim.gLimNumReassocReqDropInvldState++; -#endif - pe_debug("received ReAssoc req in state: %X from", - sta_ds->mlmStaContext.mlmState); - } - lim_print_mac_addr(mac_ctx, hdr->sa, LOGD); - lim_print_mlm_state(mac_ctx, LOGD, - (tLimMlmStates) sta_ds->mlmStaContext.mlmState); + /* Drop if STA deletion is in progress or not in established state */ + if (sta_ds->sta_deletion_in_progress || + (sta_ds->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE)) { + pe_debug("%s: peer:%pM in mlmState %d (%s) and sta del %d", + (sub_type == LIM_ASSOC) ? "Assoc" : "ReAssoc", + sta_ds->staAddr, sta_ds->mlmStaContext.mlmState, + lim_mlm_state_str(sta_ds->mlmStaContext.mlmState), + sta_ds->sta_deletion_in_progress); + lim_update_assoc_drop_count(mac_ctx, sub_type); return false; } @@ -1313,31 +1330,34 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx, pe_err("Received Assoc req in state: %X STAid: %d", sta_ds->mlmStaContext.mlmState, peer_idx); return false; - } else { - /* - * STA sent Re/association Request frame while already in - * 'associated' state. Update STA capabilities and send - * Association response frame with same AID - */ - pe_debug("Rcvd Assoc req from STA already connected"); - sta_ds->mlmStaContext.capabilityInfo = - assoc_req->capabilityInfo; - if (sta_pre_auth_ctx && (sta_pre_auth_ctx->mlmState == - eLIM_MLM_AUTHENTICATED_STATE)) { - /* STA has triggered pre-auth again */ - *auth_type = sta_pre_auth_ctx->authType; - lim_delete_pre_auth_node(mac_ctx, hdr->sa); - } else { - *auth_type = sta_ds->mlmStaContext.authType; - } - - *update_ctx = true; - if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, - &session->dph.dphHashTable) == NULL) { - pe_err("could not Init STAid: %d", peer_idx); - return false; - } } + + /* + * STA sent Re/association Request frame while already in + * 'associated' state. Update STA capabilities and send + * Association response frame with same AID + */ + pe_debug("Rcvd Assoc req from STA already connected"); + sta_ds->mlmStaContext.capabilityInfo = + assoc_req->capabilityInfo; + if (sta_pre_auth_ctx && (sta_pre_auth_ctx->mlmState == + eLIM_MLM_AUTHENTICATED_STATE)) { + /* STA has triggered pre-auth again */ + *auth_type = sta_pre_auth_ctx->authType; + lim_delete_pre_auth_node(mac_ctx, hdr->sa); + } else { + *auth_type = sta_ds->mlmStaContext.authType; + } + + *update_ctx = true; + /* Free pmf query timer before resetting the sta_ds */ + lim_delete_pmf_query_timer(sta_ds); + if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, + &session->dph.dphHashTable) == NULL) { + pe_err("could not Init STAid: %d", peer_idx); + return false; + } + return true; } @@ -1760,22 +1780,24 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, if (cfg_min(CFG_PMF_SA_QUERY_RETRY_INTERVAL) > retry_interval) { retry_interval = cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL); } - if (sta_ds->rmfEnabled && - tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer, - "PMF SA Query timer", lim_pmf_sa_query_timer_handler, - timer_id.value, - SYS_MS_TO_TICKS((retry_interval * 1024) / 1000), - 0, TX_NO_ACTIVATE) != TX_SUCCESS) { - pe_err("could not create PMF SA Query timer"); - lim_reject_association(mac_ctx, hdr->sa, sub_type, - true, auth_type, peer_idx, false, - eSIR_MAC_UNSPEC_FAILURE_STATUS, - session); - return false; + if (sta_ds->rmfEnabled) { + /* Try to delete it before, creating.*/ + lim_delete_pmf_query_timer(sta_ds); + if (tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer, + "PMF SA Query timer", lim_pmf_sa_query_timer_handler, + timer_id.value, + SYS_MS_TO_TICKS((retry_interval * 1024) / 1000), + 0, TX_NO_ACTIVATE) != TX_SUCCESS) { + pe_err("could not create PMF SA Query timer"); + lim_reject_association(mac_ctx, hdr->sa, sub_type, + true, auth_type, peer_idx, false, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + session); + return false; + } + pe_debug("Created pmf timer assoc-id:%d sta mac" QDF_MAC_ADDR_STR, + sta_ds->assocId, QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); } - if (sta_ds->rmfEnabled) - pe_debug("Created pmf timer assoc-id:%d sta mac" QDF_MAC_ADDR_STR, - sta_ds->assocId, QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); #endif if (assoc_req->ExtCap.present) { diff --git a/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c b/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c index fcbb821ea3b4..144d26228982 100644 --- a/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c +++ b/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -421,6 +421,8 @@ uint32_t tx_timer_delete(TX_TIMER *timer_ptr) } qdf_mc_timer_destroy(&timer_ptr->qdf_timer); + timer_ptr->tmrSignature = 0; + return TX_SUCCESS; } /*** tx_timer_delete() ***/