diff options
| author | Girish Gowli <c_ggowli@qti.qualcomm.com> | 2014-06-14 18:26:16 +0530 |
|---|---|---|
| committer | Pitani Venkata Rajesh Kumar <c_vpitan@qti.qualcomm.com> | 2014-07-01 12:15:49 +0530 |
| commit | 0cbf3452493ab2fa1ac8f0b80a1e28df3e3d9d68 (patch) | |
| tree | c240085d89edc1a5402e13163e3271299014a5c7 | |
| parent | 52b7e5279ecd1c6d005ac47d61aa1527a4c169ca (diff) | |
wlan: Add "compat" support in iw_setchar_getnone
The pointer passed to iw_setchar_getnone() handler is not
safe when used in a 32U/64K environment.
Add "compat" support so that when the driver is part of a
64-bit kernel, all the sub commands will work with 32-bit
userspace applications
Change-Id: I4cd48481bf69c1f4c7ca8689f133a2d4c58b85d0
CRs-Fixed: 683553
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index 621f32749d99..8b2a8c6ac2db 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -6012,7 +6012,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in union iwreq_data *wrqu, char *extra) { VOS_STATUS vstatus; - int sub_cmd = wrqu->data.flags; + int sub_cmd; int ret = 0; /* success */ char *pBuffer = NULL; hdd_adapter_t *pAdapter = (netdev_priv(dev)); @@ -6020,6 +6020,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in #ifdef WLAN_FEATURE_VOWIFI hdd_config_t *pConfig = pHddCtx->cfg_ini; #endif /* WLAN_FEATURE_VOWIFI */ + struct iw_point s_priv_data; if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { @@ -6028,9 +6029,21 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in return -EBUSY; } + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) { + return -EINVAL; + } + + /* make sure all params are correctly passed to function */ + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) { + return -EINVAL; + } + + sub_cmd = s_priv_data.flags; + /* ODD number is used for set, copy data using copy_from_user */ - pBuffer = mem_alloc_copy_from_user_helper(wrqu->data.pointer, - wrqu->data.length); + pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); if (NULL == pBuffer) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, @@ -6039,7 +6052,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in } VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, - "%s: Received length %d", __func__, wrqu->data.length); + "%s: Received length %d", __func__, s_priv_data.length); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __func__, pBuffer); @@ -6062,11 +6075,13 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in if (pConfig->fRrmEnable) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Neighbor Request"); - neighborReq.no_ssid = (wrqu->data.length - 1) ? false : true ; + neighborReq.no_ssid = (s_priv_data.length - 1) ? false : true ; if( !neighborReq.no_ssid ) { - neighborReq.ssid.length = (wrqu->data.length - 1) > 32 ? 32 : (wrqu->data.length - 1) ; - vos_mem_copy( neighborReq.ssid.ssId, pBuffer, neighborReq.ssid.length ); + neighborReq.ssid.length = (s_priv_data.length - 1) > 32 ? + 32 : (s_priv_data.length - 1); + vos_mem_copy(neighborReq.ssid.ssId, pBuffer, + neighborReq.ssid.length); } callbackInfo.neighborRspCallback = NULL; @@ -6084,7 +6099,8 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in #endif case WE_SET_AP_WPS_IE: hddLog( LOGE, "Received WE_SET_AP_WPS_IE" ); - sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer, wrqu->data.length ); + sme_updateP2pIe(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer, + s_priv_data.length); break; case WE_SET_CONFIG: vstatus = hdd_execute_global_config_command(pHddCtx, pBuffer); |
