summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPragaspathi Thilagaraj <tpragasp@codeaurora.org>2018-07-31 18:53:43 +0530
committernshrivas <nshrivas@codeaurora.org>2018-08-09 08:20:00 -0700
commitae37130a6a11606fc55c76903890a56b4be483bc (patch)
tree841f06fe8b8759aca2ca7fae146a2a19c867a940
parent40263d5a2401364d22484070a266d763c31df33a (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.h4
-rw-r--r--core/mac/src/pe/lim/lim_api.c2
-rw-r--r--core/mac/src/pe/lim/lim_process_mlm_req_messages.c21
-rw-r--r--core/wma/src/wma_dev_if.c1
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;
}