wlan: Address kernel panic due to asynchronous access of ROC context
Due to the race between supplicant thread and McThread where the
remain_on_chan context is made NULL and the __wlan_hdd_mgmt_tx
function in supplicant thread context tries to access the released
roc context results in kernel panic.
To mitigate this issue extend mutex lock to wlan_hdd_mgmt_tx function
to avoid asynchronous access to the remain_on_chan_ctx.
Change-Id: Ia70eed2e518e0fa64b86654cca3004a426f57c6b
CRs-Fixed: 771604
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index 4257539..6459b3e 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -1162,7 +1162,7 @@
rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX;
// In case of P2P Client mode if we are already
// on the same channel then send the frame directly
-
+ mutex_lock(&pHddCtx->roc_lock);
if( (cfgState->remain_on_chan_ctx != NULL) &&
(cfgState->current_freq == chan->center_freq)
)
@@ -1202,6 +1202,7 @@
hddLog(VOS_TRACE_LEVEL_INFO,
"action frame: extending the wait time %u",
wait);
+ mutex_unlock(&pHddCtx->roc_lock);
goto send_frame;
}
else
@@ -1209,6 +1210,7 @@
if ( TRUE ==
pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress )
{
+ mutex_unlock(&pHddCtx->roc_lock);
hddLog(VOS_TRACE_LEVEL_INFO,
"action frame tx: waiting for completion of ROC ");
@@ -1221,12 +1223,14 @@
"%s:wait on cancel_rem_on_chan_var failed %d",
__func__, status);
}
+ goto bypass_lock;
}
}
}
+ mutex_unlock(&pHddCtx->roc_lock);
+bypass_lock:
hddLog(VOS_TRACE_LEVEL_INFO,
"action frame: Request ROC for wait time %u", wait);
-
INIT_COMPLETION(pAdapter->offchannel_tx_event);
status = wlan_hdd_request_remain_on_channel(wiphy, dev,
chan,
@@ -1280,8 +1284,10 @@
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
if( cfgState->remain_on_chan_ctx )
{
+ mutex_lock(&pHddCtx->roc_lock);
cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie;
*cookie = cfgState->action_cookie;
+ mutex_unlock(&pHddCtx->roc_lock);
}
else
{