wlan: Validate ioctls for NULL pointer de-reference
Access to driver data structures during driver load unload
results in kernel panic.
To mitigate the issue, validate the context before accessing
driver data structures.
Change-Id: I8655ae915ab98059360c4f4bf27f52542cc8d4ff
CRs-Fixed: 787157
diff --git a/CORE/HDD/src/wlan_hdd_scan.c b/CORE/HDD/src/wlan_hdd_scan.c
index 7fd7dc7..b515570 100644
--- a/CORE/HDD/src/wlan_hdd_scan.c
+++ b/CORE/HDD/src/wlan_hdd_scan.c
@@ -672,18 +672,42 @@
int __iw_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
+ hdd_adapter_t *pAdapter;
+ hdd_context_t *pHddCtx;
+ hdd_wext_state_t *pwextBuf;
tCsrScanRequest scanRequest;
v_U32_t scanId = 0;
eHalStatus status = eHAL_STATUS_SUCCESS;
struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
+ int ret = 0;
ENTER();
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
+ pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Adapter is NULL",__func__);
+ return -EINVAL;
+ }
+
+ 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;
+ }
+ pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
+ if (NULL == pwextBuf)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: pwextBuf is NULL",__func__);
+ return -EINVAL;
+ }
#ifdef WLAN_BTAMP_FEATURE
//Scan not supported when AMP traffic is on.
if( VOS_TRUE == WLANBAP_AmpSessionOn() )
@@ -698,10 +722,6 @@
return eHAL_STATUS_SUCCESS;
}
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return eHAL_STATUS_SUCCESS;
- }
vos_mem_zero( &scanRequest, sizeof(scanRequest));
if (NULL != wrqu->data.pointer)
@@ -856,30 +876,48 @@
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
+ hdd_adapter_t *pAdapter;
+ hdd_context_t *pHddCtx;
+ tHalHandle hHal;
tCsrScanResultInfo *pScanResult;
eHalStatus status = eHAL_STATUS_SUCCESS;
hdd_scan_info_t scanInfo;
tScanResultHandle pResult;
- int i = 0;
+ int i = 0, ret = 0;
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!",
__func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA);
ENTER();
+ pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Adapter is NULL",__func__);
+ return -EINVAL;
+ }
+
+ 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;
+ }
+ hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
+ if (NULL == hHal)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Hal Context is NULL",__func__);
+ return -EINVAL;
+ }
+
if (TRUE == pHddCtx->scan_info.mScanPending)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
return -EAGAIN;
}
-
- if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
- return -EAGAIN;
- }
-
scanInfo.dev = dev;
scanInfo.start = extra;
scanInfo.info = info;