wlan: Protect cfg ops function from SSR
If SSR is in middle of progress, cfg ops handler needs to
validate the hdd context to avoid any uninitialized data
access.
Change-Id: I4924cd3c153d9a4f64b8d0cca7ace0726e85c366
CRs-Fixed: 783966
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 0fb491d..b022c69 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -7258,9 +7258,27 @@
struct bss_parameters *params)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *pHddCtx;
+ int ret = 0;
ENTER();
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD adapter is Null", __func__);
+ return -ENODEV;
+ }
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return ret;
+ }
+
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
pAdapter->sessionId, params->ap_isolate));
@@ -7952,6 +7970,7 @@
hdd_context_t *pHddCtx;
hdd_station_ctx_t *pHddStaCtx;
v_MACADDR_t STAMacAddress;
+ int ret = 0;
#ifdef FEATURE_WLAN_TDLS
tCsrStaParams StaParams = {0};
tANI_U8 isBufSta = 0;
@@ -7970,20 +7989,22 @@
TRACE_CODE_HDD_CHANGE_STATION,
pAdapter->sessionId, params->listen_interval));
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "invalid HDD state or HDD station context");
- return -EINVAL;
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return ret;
}
- if (pHddCtx->isLogpInProgress)
+ pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+
+ if (NULL == pHddStaCtx)
{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EAGAIN;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "invalid HDD station context");
+ return -EINVAL;
}
vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
@@ -8567,12 +8588,33 @@
#endif
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
- hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
+ hdd_wext_state_t *pWextState = NULL;
+ tCsrRoamProfile *pRoamProfile = NULL;
struct key_params params;
+ hdd_context_t *pHddCtx;
+ int ret = 0;
ENTER();
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD adapter is Null", __func__);
+ return -ENODEV;
+ }
+
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return ret;
+ }
+
+ pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
+ pRoamProfile = &(pWextState->roamProfile);
+
hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
__func__, hdd_device_modetoString(pAdapter->device_mode),
pAdapter->device_mode);
@@ -13328,6 +13370,8 @@
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_station_ctx_t *pHddStaCtx;
+ hdd_context_t *pHddCtx;
+ int ret = 0;
if (NULL == pAdapter)
{
@@ -13335,6 +13379,15 @@
return -ENODEV;
}
+ pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return ret;
+ }
+
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
@@ -14981,6 +15034,13 @@
#ifdef FEATURE_WLAN_LPHB
hdd_context_t *pHddCtx = wiphy_priv(wiphy);
eHalStatus smeStatus;
+ err = wlan_hdd_validate_context(pHddCtx);
+ if (0 != err)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return err;
+ }
#endif /* FEATURE_WLAN_LPHB */
err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
@@ -15290,15 +15350,18 @@
struct cfg80211_wowlan *wow)
{
hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ int ret = 0;
ENTER();
- if (NULL == pHddCtx)
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
{
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
- "%s: HddCtx validation failed", __func__);
- return 0;
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return ret;
}
+
pHddCtx->isWiphySuspended = TRUE;
EXIT();
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index ed2279f..cbff04a 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -560,9 +560,27 @@
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_remain_on_chan_ctx_t *pRemainChanCtx;
hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
+ hdd_context_t *pHddCtx = NULL;
VOS_STATUS checkReadyInd;
hdd_adapter_t *pStaAdapter;
+ int status = 0;
+
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD adapter is Null", __func__);
+ return -ENODEV;
+ }
+
+ pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
+ status = wlan_hdd_validate_context(pHddCtx);
+
+ if (0 != status)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+ return status;
+ }
hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
__func__,pAdapter->device_mode);
@@ -590,20 +608,13 @@
* wlan driver is keep on receiving the remain on channel command
* and which is resulting in crash. So not allowing any remain on
* channel requets when Load/Unload is in progress*/
- if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(((hdd_context_t *)pAdapter->pHddCtx))
- || hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx))
+ if(hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx))
{
hddLog( LOGE,
- "%s: Wlan Load/Unload or Connection is in progress", __func__);
+ "%s: Connection is in progress", __func__);
return -EBUSY;
}
- if (((hdd_context_t*)pAdapter->pHddCtx)->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s:LOGP in Progress. Ignore!!!", __func__);
- return -EAGAIN;
- }
pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) );
if( NULL == pRemainChanCtx )
{
@@ -1827,8 +1838,21 @@
hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
hdd_adapter_t *pAdapter = NULL;
hdd_scaninfo_t *pScanInfo = NULL;
+ int ret = 0;
ENTER();
+ ret = wlan_hdd_validate_context(pHddCtx);
+ if (0 != ret)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD context is not valid", __func__);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
+ return ERR_PTR(-EINVAL);
+#else
+ return -EAGAIN;
+#endif
+ }
+
MTRACE(vos_trace(VOS_MODULE_ID_HDD,
TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type));
if (WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) &&
@@ -1844,17 +1868,6 @@
#endif
}
- if (pHddCtx->isLogpInProgress)
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "%s:LOGP in Progress. Ignore!!!", __func__);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
- return ERR_PTR(-EINVAL);
-#else
- return -EAGAIN;
-#endif
- }
-
pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
pScanInfo = &pHddCtx->scan_info;
if ((pScanInfo != NULL) && (pAdapter != NULL) &&