mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
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:
parent
77aca6ed3c
commit
7a7799b04a
2 changed files with 85 additions and 61 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() ***/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue