mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
qcacld-3.0: Fix memory double free
The lim_deauth_tx_complete_cnf and lim_disassoc_tx_complete_cnf are called in data path softirq thread. The lim_process_deauth_ack_timeout are called in pe context in scheduler thread. Both thread will call lim_send_deauth_cnf to free lim.limDisassocDeauthCnfReq.pMlmDeauthReq. Fix by posting WMA_DISASSOC_TX_COMP and WMA_DEAUTH_TX_COMP to scheduler thread. Let lim_disassoc_tx_complete_cnf and lim_deauth_tx_complete_cnf run in correct PE thread context. Change-Id: I83a4ad741da46aa907603ae587c74042730b67bd CRs-Fixed: 2143794
This commit is contained in:
parent
5ad8d872de
commit
c0b2e333be
3 changed files with 113 additions and 74 deletions
|
|
@ -1766,10 +1766,12 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
|
|||
msg->bodyptr = NULL;
|
||||
break;
|
||||
case WMA_DISASSOC_TX_COMP:
|
||||
lim_disassoc_tx_complete_cnf(mac_ctx, NULL, msg->bodyval, NULL);
|
||||
lim_disassoc_tx_complete_cnf(mac_ctx, msg->bodyval,
|
||||
msg->bodyptr);
|
||||
break;
|
||||
case WMA_DEAUTH_TX_COMP:
|
||||
lim_deauth_tx_complete_cnf(mac_ctx, NULL, msg->bodyval, NULL);
|
||||
lim_deauth_tx_complete_cnf(mac_ctx, msg->bodyval,
|
||||
msg->bodyptr);
|
||||
break;
|
||||
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
|
||||
case WMA_UPDATE_Q2Q_IE_IND:
|
||||
|
|
|
|||
|
|
@ -2453,90 +2453,91 @@ alloc_packet:
|
|||
return;
|
||||
}
|
||||
|
||||
QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
|
||||
QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal mac_ctx)
|
||||
{
|
||||
uint16_t aid;
|
||||
tpDphHashNode pStaDs;
|
||||
tLimMlmDeauthReq *pMlmDeauthReq;
|
||||
tLimMlmDeauthCnf mlmDeauthCnf;
|
||||
tpPESession psessionEntry;
|
||||
tpDphHashNode sta_ds;
|
||||
tLimMlmDeauthReq *deauth_req;
|
||||
tLimMlmDeauthCnf deauth_cnf;
|
||||
tpPESession session_entry;
|
||||
|
||||
pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
|
||||
if (pMlmDeauthReq) {
|
||||
if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
|
||||
lim_deactivate_and_change_timer(pMac,
|
||||
deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
|
||||
if (deauth_req) {
|
||||
if (tx_timer_running(
|
||||
&mac_ctx->lim.limTimers.gLimDeauthAckTimer))
|
||||
lim_deactivate_and_change_timer(mac_ctx,
|
||||
eLIM_DEAUTH_ACK_TIMER);
|
||||
}
|
||||
|
||||
psessionEntry = pe_find_session_by_session_id(pMac,
|
||||
pMlmDeauthReq->sessionId);
|
||||
if (psessionEntry == NULL) {
|
||||
session_entry = pe_find_session_by_session_id(mac_ctx,
|
||||
deauth_req->sessionId);
|
||||
if (session_entry == NULL) {
|
||||
pe_err("session does not exist for given sessionId");
|
||||
mlmDeauthCnf.resultCode =
|
||||
deauth_cnf.resultCode =
|
||||
eSIR_SME_INVALID_PARAMETERS;
|
||||
goto end;
|
||||
}
|
||||
|
||||
pStaDs =
|
||||
dph_lookup_hash_entry(pMac,
|
||||
pMlmDeauthReq->peer_macaddr.bytes,
|
||||
sta_ds =
|
||||
dph_lookup_hash_entry(mac_ctx,
|
||||
deauth_req->peer_macaddr.bytes,
|
||||
&aid,
|
||||
&psessionEntry->dph.dphHashTable);
|
||||
if (pStaDs == NULL) {
|
||||
mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
|
||||
&session_entry->dph.dphHashTable);
|
||||
if (sta_ds == NULL) {
|
||||
deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* / Receive path cleanup with dummy packet */
|
||||
lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
|
||||
lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
|
||||
if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
|
||||
(
|
||||
lim_ft_cleanup_pre_auth_info(mac_ctx, session_entry);
|
||||
lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
|
||||
if ((session_entry->limSystemRole == eLIM_STA_ROLE) &&
|
||||
(
|
||||
#ifdef FEATURE_WLAN_ESE
|
||||
(psessionEntry->isESEconnection) ||
|
||||
(session_entry->isESEconnection) ||
|
||||
#endif
|
||||
(psessionEntry->isFastRoamIniFeatureEnabled) ||
|
||||
(psessionEntry->is11Rconnection))) {
|
||||
(session_entry->isFastRoamIniFeatureEnabled) ||
|
||||
(session_entry->is11Rconnection))) {
|
||||
pe_debug("FT Preauth (%pK,%d) Deauth rc %d src = %d",
|
||||
psessionEntry,
|
||||
psessionEntry->peSessionId,
|
||||
pMlmDeauthReq->reasonCode,
|
||||
pMlmDeauthReq->deauthTrigger);
|
||||
lim_ft_cleanup(pMac, psessionEntry);
|
||||
session_entry,
|
||||
session_entry->peSessionId,
|
||||
deauth_req->reasonCode,
|
||||
deauth_req->deauthTrigger);
|
||||
lim_ft_cleanup(mac_ctx, session_entry);
|
||||
} else {
|
||||
pe_debug("No FT Preauth Session Cleanup in role %d"
|
||||
#ifdef FEATURE_WLAN_ESE
|
||||
" isESE %d"
|
||||
" isESE %d"
|
||||
#endif
|
||||
" isLFR %d"
|
||||
" is11r %d, Deauth reason %d Trigger = %d",
|
||||
psessionEntry->limSystemRole,
|
||||
" isLFR %d"
|
||||
" is11r %d, Deauth reason %d Trigger = %d",
|
||||
session_entry->limSystemRole,
|
||||
#ifdef FEATURE_WLAN_ESE
|
||||
psessionEntry->isESEconnection,
|
||||
session_entry->isESEconnection,
|
||||
#endif
|
||||
psessionEntry->isFastRoamIniFeatureEnabled,
|
||||
psessionEntry->is11Rconnection,
|
||||
pMlmDeauthReq->reasonCode,
|
||||
pMlmDeauthReq->deauthTrigger);
|
||||
session_entry->isFastRoamIniFeatureEnabled,
|
||||
session_entry->is11Rconnection,
|
||||
deauth_req->reasonCode,
|
||||
deauth_req->deauthTrigger);
|
||||
}
|
||||
/* Free up buffer allocated for mlmDeauthReq */
|
||||
qdf_mem_free(pMlmDeauthReq);
|
||||
pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
|
||||
qdf_mem_free(deauth_req);
|
||||
mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
end:
|
||||
qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr,
|
||||
&pMlmDeauthReq->peer_macaddr);
|
||||
mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
|
||||
mlmDeauthCnf.aid = pMlmDeauthReq->aid;
|
||||
mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
|
||||
qdf_copy_macaddr(&deauth_cnf.peer_macaddr,
|
||||
&deauth_req->peer_macaddr);
|
||||
deauth_cnf.deauthTrigger = deauth_req->deauthTrigger;
|
||||
deauth_cnf.aid = deauth_req->aid;
|
||||
deauth_cnf.sessionId = deauth_req->sessionId;
|
||||
|
||||
/* Free up buffer allocated */
|
||||
/* for mlmDeauthReq */
|
||||
qdf_mem_free(pMlmDeauthReq);
|
||||
qdf_mem_free(deauth_req);
|
||||
mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
|
||||
|
||||
lim_post_sme_message(pMac,
|
||||
LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
|
||||
lim_post_sme_message(mac_ctx,
|
||||
LIM_MLM_DEAUTH_CNF, (uint32_t *) &deauth_cnf);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -2592,10 +2593,10 @@ QDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
|
|||
goto end;
|
||||
}
|
||||
if (LIM_IS_STA_ROLE(pe_session) &&
|
||||
(disassoc_req->reasonCode !=
|
||||
eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
|
||||
(disassoc_req->reasonCode !=
|
||||
eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
|
||||
pe_debug("FT Preauth Session (%pK %d) Clean up",
|
||||
pe_session, pe_session->peSessionId);
|
||||
pe_session, pe_session->peSessionId);
|
||||
|
||||
/* Delete FT session if there exists one */
|
||||
lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
|
||||
|
|
@ -2629,33 +2630,73 @@ end:
|
|||
}
|
||||
|
||||
QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
|
||||
qdf_nbuf_t buf,
|
||||
uint32_t txCompleteSuccess,
|
||||
uint32_t tx_success,
|
||||
void *params)
|
||||
{
|
||||
tpAniSirGlobal pMac = (tpAniSirGlobal)context;
|
||||
tpAniSirGlobal max_ctx = (tpAniSirGlobal)context;
|
||||
|
||||
pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
|
||||
pe_debug("tx_success: %d", tx_success);
|
||||
|
||||
return lim_send_disassoc_cnf(max_ctx);
|
||||
}
|
||||
|
||||
static QDF_STATUS lim_disassoc_tx_complete_cnf_handler(void *context,
|
||||
qdf_nbuf_t buf,
|
||||
uint32_t tx_success,
|
||||
void *params)
|
||||
{
|
||||
tpAniSirGlobal max_ctx = (tpAniSirGlobal)context;
|
||||
QDF_STATUS status_code;
|
||||
struct scheduler_msg msg = {0};
|
||||
|
||||
pe_debug("tx_success: %d", tx_success);
|
||||
|
||||
if (buf)
|
||||
qdf_nbuf_free(buf);
|
||||
msg.type = (uint16_t) WMA_DISASSOC_TX_COMP;
|
||||
msg.bodyptr = params;
|
||||
msg.bodyval = tx_success;
|
||||
|
||||
return lim_send_disassoc_cnf(pMac);
|
||||
status_code = lim_post_msg_high_priority(max_ctx, &msg);
|
||||
if (status_code != QDF_STATUS_SUCCESS)
|
||||
pe_err("posting message: %X to LIM failed, reason: %d",
|
||||
msg.type, status_code);
|
||||
return status_code;
|
||||
}
|
||||
|
||||
QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
|
||||
qdf_nbuf_t buf,
|
||||
uint32_t txCompleteSuccess,
|
||||
uint32_t tx_success,
|
||||
void *params)
|
||||
{
|
||||
tpAniSirGlobal pMac = (tpAniSirGlobal)context;
|
||||
tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
|
||||
|
||||
pe_debug("txCompleteSuccess: %d", txCompleteSuccess);
|
||||
pe_debug("tx_success: %d", tx_success);
|
||||
|
||||
return lim_send_deauth_cnf(mac_ctx);
|
||||
}
|
||||
|
||||
static QDF_STATUS lim_deauth_tx_complete_cnf_handler(void *context,
|
||||
qdf_nbuf_t buf,
|
||||
uint32_t tx_success,
|
||||
void *params)
|
||||
{
|
||||
tpAniSirGlobal mac_ctx = (tpAniSirGlobal)context;
|
||||
QDF_STATUS status_code;
|
||||
struct scheduler_msg msg = {0};
|
||||
|
||||
pe_debug("tx_success: %d", tx_success);
|
||||
|
||||
if (buf)
|
||||
qdf_nbuf_free(buf);
|
||||
msg.type = (uint16_t) WMA_DEAUTH_TX_COMP;
|
||||
msg.bodyptr = params;
|
||||
msg.bodyval = tx_success;
|
||||
|
||||
return lim_send_deauth_cnf(pMac);
|
||||
status_code = lim_post_msg_high_priority(mac_ctx, &msg);
|
||||
if (status_code != QDF_STATUS_SUCCESS)
|
||||
pe_err("posting message: %X to LIM failed, reason: %d",
|
||||
msg.type, status_code);
|
||||
return status_code;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2784,7 +2825,7 @@ lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
|
|||
wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
|
||||
TXRX_FRM_802_11_MGMT,
|
||||
ANI_TXDIR_TODS, 7, lim_tx_complete,
|
||||
pFrame, lim_disassoc_tx_complete_cnf,
|
||||
pFrame, lim_disassoc_tx_complete_cnf_handler,
|
||||
txFlag, smeSessionId, false, 0,
|
||||
RATEID_DEFAULT);
|
||||
MTRACE(qdf_trace
|
||||
|
|
@ -2960,7 +3001,7 @@ lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
|
|||
wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
|
||||
TXRX_FRM_802_11_MGMT,
|
||||
ANI_TXDIR_TODS, 7, lim_tx_complete,
|
||||
pFrame, lim_deauth_tx_complete_cnf,
|
||||
pFrame, lim_deauth_tx_complete_cnf_handler,
|
||||
txFlag, smeSessionId, false, 0,
|
||||
RATEID_DEFAULT);
|
||||
MTRACE(qdf_trace
|
||||
|
|
|
|||
|
|
@ -898,7 +898,6 @@ QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac);
|
|||
/**
|
||||
* lim_disassoc_tx_complete_cnf() - callback to indicate Tx completion
|
||||
* @context: pointer to mac structure
|
||||
* @buf: buffer
|
||||
* @txCompleteSuccess: indicates tx success/failure
|
||||
* @params: tx completion params
|
||||
*
|
||||
|
|
@ -907,14 +906,12 @@ QDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac);
|
|||
* return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
|
||||
*/
|
||||
QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
|
||||
qdf_nbuf_t buf,
|
||||
uint32_t txCompleteSuccess,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* lim_deauth_tx_complete_cnf() - callback to indicate Tx completion
|
||||
* @context: pointer to mac structure
|
||||
* @buf: buffer
|
||||
* @txCompleteSuccess: indicates tx success/failure
|
||||
* @params: tx completion params
|
||||
*
|
||||
|
|
@ -923,7 +920,6 @@ QDF_STATUS lim_disassoc_tx_complete_cnf(void *context,
|
|||
* return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
|
||||
*/
|
||||
QDF_STATUS lim_deauth_tx_complete_cnf(void *context,
|
||||
qdf_nbuf_t buf,
|
||||
uint32_t txCompleteSuccess,
|
||||
void *params);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue