summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNitesh Shah <niteshs@codeaurora.org>2017-02-06 15:24:59 +0530
committerqcabuildsw <qcabuildsw@localhost>2017-02-07 17:40:33 -0800
commit074df69593a37c5dedc82db77d1ebbabcfa10ced (patch)
tree8d9288053626baa6b965628981447b7cb18e2038
parenta2d11331f33e8642862c10bdb8409978f4046d9d (diff)
qcacld-3.0: Protect ROC ctx with mutex lock during ROC callback
Multiple functions running in different thread context can access the ROC context or alter its elements, after the roc context is freed or its elements are altered by other functions which can lead to crash or some other issues. To address this, protect ROC context and its elements with mutex. The possible scenarios addressed are during roc callback, roc timeout and cancel roc. Change-Id: I2c79216f71c720cd4b555061e8a69adab50dda5e CRs-Fixed: 2002644
-rw-r--r--core/hdd/src/wlan_hdd_p2p.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c
index 014ec754012c..79f1cb01b8df 100644
--- a/core/hdd/src/wlan_hdd_p2p.c
+++ b/core/hdd/src/wlan_hdd_p2p.c
@@ -169,6 +169,7 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
hdd_remain_on_chan_ctx_t *pRemainChanCtx;
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
+ rem_on_channel_request_type_t req_type;
if (!hdd_ctx) {
hdd_err("Invalid HDD context");
@@ -206,7 +207,6 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
* progress.
*/
hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC);
- mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
if (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) {
if (cfgState->buf) {
@@ -222,6 +222,8 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
pAdapter->last_roc_ts =
(uint64_t)qdf_mc_timer_get_system_time();
}
+ req_type = pRemainChanCtx->rem_on_chan_request;
+ mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
/* Schedule any pending RoC: Any new roc request during this time
* would have got queued in 'wlan_hdd_request_remain_on_channel'
@@ -237,8 +239,7 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
(QDF_P2P_DEVICE_MODE == pAdapter->device_mode)
) {
uint8_t sessionId = pAdapter->sessionId;
- if (REMAIN_ON_CHANNEL_REQUEST ==
- pRemainChanCtx->rem_on_chan_request) {
+ if (REMAIN_ON_CHANNEL_REQUEST == req_type) {
sme_deregister_mgmt_frame(hHal, sessionId,
(SIR_MAC_MGMT_FRAME << 2) |
(SIR_MAC_MGMT_PROBE_REQ << 4),
@@ -255,13 +256,17 @@ QDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
}
- if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL
- && pRemainChanCtx->action_pkt_buff.frame_length != 0) {
- qdf_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
- pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
- pRemainChanCtx->action_pkt_buff.frame_length = 0;
+ mutex_lock(&cfgState->remain_on_chan_ctx_lock);
+ if (pRemainChanCtx) {
+ if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL
+ && pRemainChanCtx->action_pkt_buff.frame_length != 0) {
+ qdf_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
+ pRemainChanCtx->action_pkt_buff.frame_ptr = NULL;
+ pRemainChanCtx->action_pkt_buff.frame_length = 0;
+ }
}
qdf_mem_free(pRemainChanCtx);
+ mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
complete(&pAdapter->cancel_rem_on_chan_var);
if (QDF_STATUS_SUCCESS != status)
complete(&pAdapter->rem_on_chan_ready_event);
@@ -484,6 +489,7 @@ static void wlan_hdd_remain_on_chan_timeout(void *data)
hdd_remain_on_chan_ctx_t *pRemainChanCtx;
hdd_cfg80211_state_t *cfgState;
hdd_context_t *hdd_ctx;
+ uint32_t roc_scan_id;
if ((NULL == pAdapter) ||
(WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
@@ -509,6 +515,7 @@ static void wlan_hdd_remain_on_chan_timeout(void *data)
}
pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = true;
+ roc_scan_id = pRemainChanCtx->scan_id;
mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
hdd_notice("Cancel Remain on Channel on timeout");
@@ -517,14 +524,13 @@ static void wlan_hdd_remain_on_chan_timeout(void *data)
(QDF_P2P_DEVICE_MODE == pAdapter->device_mode)
) {
sme_cancel_remain_on_channel(WLAN_HDD_GET_HAL_CTX(pAdapter),
- pAdapter->sessionId,
- pRemainChanCtx->scan_id);
+ pAdapter->sessionId, roc_scan_id);
} else if ((QDF_SAP_MODE == pAdapter->device_mode) ||
(QDF_P2P_GO_MODE == pAdapter->device_mode)
) {
wlansap_cancel_remain_on_channel(
(WLAN_HDD_GET_CTX(pAdapter))->pcds_context,
- pRemainChanCtx->scan_id);
+ roc_scan_id);
}
hdd_restart_tdls_source_timer(hdd_ctx, hdd_ctx->tdls_mode_last);
@@ -1090,6 +1096,7 @@ __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
unsigned long rc;
qdf_list_node_t *tmp, *q;
hdd_roc_req_t *curr_roc_req;
+ uint32_t roc_scan_id;
ENTER();
@@ -1156,6 +1163,7 @@ __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress =
true;
}
+ roc_scan_id = pRemainChanCtx->scan_id;
mutex_unlock(&cfgState->remain_on_chan_ctx_lock);
/* wait until remain on channel ready event received
@@ -1187,14 +1195,12 @@ __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
uint8_t sessionId = pAdapter->sessionId;
sme_cancel_remain_on_channel(WLAN_HDD_GET_HAL_CTX(pAdapter),
- sessionId,
- pRemainChanCtx->scan_id);
+ sessionId, roc_scan_id);
} else if ((QDF_SAP_MODE == pAdapter->device_mode) ||
(QDF_P2P_GO_MODE == pAdapter->device_mode)
) {
wlansap_cancel_remain_on_channel(
- WLAN_HDD_GET_SAP_CTX_PTR(pAdapter),
- pRemainChanCtx->scan_id);
+ WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), roc_scan_id);
} else {
hdd_err("Invalid device_mode %s(%d)",