diff options
| author | Pragaspathi Thilagaraj <tpragasp@codeaurora.org> | 2018-07-31 18:53:43 +0530 |
|---|---|---|
| committer | nshrivas <nshrivas@codeaurora.org> | 2018-08-09 08:20:00 -0700 |
| commit | ae37130a6a11606fc55c76903890a56b4be483bc (patch) | |
| tree | 841f06fe8b8759aca2ca7fae146a2a19c867a940 | |
| parent | 40263d5a2401364d22484070a266d763c31df33a (diff) | |
qcacld-3.0: Fix memory corruption in pe_free_nested_messages
When peer creation fails in wma_set_link_state, wma sends the
WMA_SET_LINK_STATE_RSP msg to LIM and Lim frees the msg->bodyptr
But there is a situation occurs where after this wma_peer_create
fails, mc thread stop sys event also occurs where the mac_stop
is invoked which calls the pe_free_msg -> pe_free_nested_messages
In pe_free_nested_messages, if the msg type is
WMA_SET_LINK_STATE_RSP, we free the msg->bodyptr->callbackArg.
This callbackArg points to the PE session. Trying to free the
PE session results in memory corruption.
Just pass the session id as callback argument when the callback
is lim_post_join_set_link_state_callback.
Change-Id: I27f9127685ac7ef8d215b135f1625e8e2f225fc0
CRs-Fixed: 2287827
| -rw-r--r-- | core/mac/src/pe/include/lim_session.h | 4 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_api.c | 2 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_mlm_req_messages.c | 21 | ||||
| -rw-r--r-- | core/wma/src/wma_dev_if.c | 1 |
4 files changed, 26 insertions, 2 deletions
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index aa2663b1f879..0e8275a3c990 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -83,6 +83,10 @@ typedef struct join_params { tSirResultCodes result_code; } join_params; +struct session_params { + uint16_t session_id; +}; + typedef struct sPESession /* Added to Support BT-AMP */ { /* To check session table is in use or free */ diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index c14be9b74fd8..1ac14a200920 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -890,6 +890,7 @@ tSirRetStatus pe_start(tpAniSirGlobal pMac) void pe_stop(tpAniSirGlobal pMac) { lim_cleanup(pMac); + pe_debug(" PE STOP: Set LIM state to eLIM_MLM_OFFLINE_STATE"); SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE); return; } @@ -898,6 +899,7 @@ static void pe_free_nested_messages(tSirMsgQ *msg) { switch (msg->type) { case WMA_SET_LINK_STATE_RSP: + pe_debug("pe_free_nested_messages: WMA_SET_LINK_STATE_RSP"); qdf_mem_free(((tpLinkStateParams) msg->bodyptr)->callbackArg); break; default: diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index b86b8f8e0d50..abf7e953439b 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -764,8 +764,16 @@ static void lim_post_join_set_link_state_callback(tpAniSirGlobal mac, void *callback_arg, bool status) { uint8_t chan_num, sec_chan_offset; - tpPESession session_entry = (tpPESession) callback_arg; + struct session_params *session_cb_param = + (struct session_params *) callback_arg; tLimMlmJoinCnf mlm_join_cnf; + tpPESession session_entry = pe_find_session_by_session_id(mac, + session_cb_param->session_id); + if (session_entry == NULL) { + pe_err("sessionId:%d does not exist", + session_cb_param->session_id); + return; + } pe_debug("Sessionid %d set link state(%d) cb status: %d", session_entry->peSessionId, session_entry->limMlmState, @@ -835,6 +843,7 @@ lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx, tLimMlmJoinCnf mlm_join_cnf; tpPESession session = (tpPESession) ctx; tSirLinkState lnk_state; + struct session_params *pe_session_param = NULL; if (QDF_STATUS_SUCCESS != status) { pe_err("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join", @@ -850,11 +859,18 @@ lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx, pe_debug("[lim_process_mlm_join_req]: lnk_state: %d", lnk_state); + pe_session_param = qdf_mem_malloc(sizeof(struct session_params)); + if (pe_session_param != NULL) { + pe_session_param->session_id = session->peSessionId; + } else { + pe_err("insufficient memory"); + goto error; + } if (lim_set_link_state(mac_ctx, lnk_state, session->pLimMlmJoinReq->bssDescription.bssId, session->selfMacAddr, lim_post_join_set_link_state_callback, - session) != eSIR_SUCCESS) { + pe_session_param) != eSIR_SUCCESS) { pe_err("SessionId:%d lim_set_link_state to eSIR_LINK_PREASSOC_STATE Failed!!", session->peSessionId); lim_print_mac_addr(mac_ctx, @@ -863,6 +879,7 @@ lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx, session->limMlmState = eLIM_MLM_IDLE_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, session->limMlmState)); + qdf_mem_free(pe_session_param); goto error; } diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 73e8361e00df..88129db144e5 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1649,6 +1649,7 @@ static void wma_cleanup_target_req_param(struct wma_target_req *tgt_req) tpLinkStateParams params = (tpLinkStateParams) tgt_req->user_data; qdf_mem_free(params->callbackArg); + params->callbackArg = NULL; qdf_mem_free(tgt_req->user_data); tgt_req->user_data = NULL; } |
