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
This commit is contained in:
@@ -1197,6 +1197,36 @@ static bool lim_process_assoc_req_no_sta_ctx(struct mac_context *mac_ctx,
|
|||||||
return true;
|
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
|
* lim_process_assoc_req_sta_ctx() - process assoc req for sta context present
|
||||||
* @mac_ctx: pointer to Global MAC structure
|
* @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,
|
tpDphHashNode sta_ds, uint16_t peer_idx,
|
||||||
tAniAuthType *auth_type, uint8_t *update_ctx)
|
tAniAuthType *auth_type, uint8_t *update_ctx)
|
||||||
{
|
{
|
||||||
/* STA context does exist for this STA */
|
/* Drop if STA deletion is in progress or not in established state */
|
||||||
if (sta_ds->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
|
if (sta_ds->sta_deletion_in_progress ||
|
||||||
/*
|
(sta_ds->mlmStaContext.mlmState !=
|
||||||
* Requesting STA is in some 'transient' state? Ignore the
|
eLIM_MLM_LINK_ESTABLISHED_STATE)) {
|
||||||
* Re/Assoc Req frame by incrementing debug counter & logging
|
pe_debug("%s: peer:%pM in mlmState %d (%s) and sta del %d",
|
||||||
* error.
|
(sub_type == LIM_ASSOC) ? "Assoc" : "ReAssoc",
|
||||||
*/
|
sta_ds->staAddr, sta_ds->mlmStaContext.mlmState,
|
||||||
if (sub_type == LIM_ASSOC) {
|
lim_mlm_state_str(sta_ds->mlmStaContext.mlmState),
|
||||||
#ifdef WLAN_DEBUG
|
sta_ds->sta_deletion_in_progress);
|
||||||
mac_ctx->lim.gLimNumAssocReqDropInvldState++;
|
lim_update_assoc_drop_count(mac_ctx, sub_type);
|
||||||
#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);
|
|
||||||
return false;
|
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",
|
pe_err("Received Assoc req in state: %X STAid: %d",
|
||||||
sta_ds->mlmStaContext.mlmState, peer_idx);
|
sta_ds->mlmStaContext.mlmState, peer_idx);
|
||||||
return false;
|
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;
|
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) {
|
if (cfg_min(CFG_PMF_SA_QUERY_RETRY_INTERVAL) > retry_interval) {
|
||||||
retry_interval = cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL);
|
retry_interval = cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL);
|
||||||
}
|
}
|
||||||
if (sta_ds->rmfEnabled &&
|
if (sta_ds->rmfEnabled) {
|
||||||
tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer,
|
/* Try to delete it before, creating.*/
|
||||||
"PMF SA Query timer", lim_pmf_sa_query_timer_handler,
|
lim_delete_pmf_query_timer(sta_ds);
|
||||||
timer_id.value,
|
if (tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer,
|
||||||
SYS_MS_TO_TICKS((retry_interval * 1024) / 1000),
|
"PMF SA Query timer", lim_pmf_sa_query_timer_handler,
|
||||||
0, TX_NO_ACTIVATE) != TX_SUCCESS) {
|
timer_id.value,
|
||||||
pe_err("could not create PMF SA Query timer");
|
SYS_MS_TO_TICKS((retry_interval * 1024) / 1000),
|
||||||
lim_reject_association(mac_ctx, hdr->sa, sub_type,
|
0, TX_NO_ACTIVATE) != TX_SUCCESS) {
|
||||||
true, auth_type, peer_idx, false,
|
pe_err("could not create PMF SA Query timer");
|
||||||
eSIR_MAC_UNSPEC_FAILURE_STATUS,
|
lim_reject_association(mac_ctx, hdr->sa, sub_type,
|
||||||
session);
|
true, auth_type, peer_idx, false,
|
||||||
return 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
|
#endif
|
||||||
|
|
||||||
if (assoc_req->ExtCap.present) {
|
if (assoc_req->ExtCap.present) {
|
||||||
|
@@ -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
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* 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);
|
qdf_mc_timer_destroy(&timer_ptr->qdf_timer);
|
||||||
|
timer_ptr->tmrSignature = 0;
|
||||||
|
|
||||||
return TX_SUCCESS;
|
return TX_SUCCESS;
|
||||||
} /*** tx_timer_delete() ***/
|
} /*** tx_timer_delete() ***/
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user