DivestOS/Patches/Linux_CVEs/CVE-2016-2470/ANY/0001.patch
2017-11-07 17:32:46 -05:00

304 lines
13 KiB
Diff

From 05ce237387c6e1d101bbb4b825e56757576748e6 Mon Sep 17 00:00:00 2001
From: Arif Hussain <c_arifh@qca.qualcomm.com>
Date: Mon, 11 Nov 2013 22:59:34 -0800
Subject: wlan: wlan_hdd_wext Userspace data copy fix
Use copy_to_user and copy_from_user for
copying data to/from user space.
Change-Id: I98fb6352b654af8f78160738e7ccd902c3c70031
CRs-Fixed: 561028
---
CORE/HDD/src/wlan_hdd_wext.c | 75 +++++++++++++++++++++++++-------------------
1 file changed, 42 insertions(+), 33 deletions(-)
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index c5247d3..6d60f14 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -1385,7 +1385,7 @@ static int iw_set_genie(struct net_device *dev,
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
- u_int8_t *genie;
+ u_int8_t *genie = (u_int8_t *)extra;
v_U16_t remLen;
ENTER();
@@ -1400,7 +1400,6 @@ static int iw_set_genie(struct net_device *dev,
return 0;
}
- genie = wrqu->data.pointer;
remLen = wrqu->data.length;
hddLog(LOG1,"iw_set_genie ioctl IE[0x%X], LEN[%d]\n", genie[0], genie[1]);
@@ -1528,9 +1527,14 @@ static int iw_get_genie(struct net_device *dev,
pAdapter->sessionId,
&length,
genIeBytes);
- wrqu->data.length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
-
- vos_mem_copy( wrqu->data.pointer, (v_VOID_t*)genIeBytes, wrqu->data.length);
+ length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
+ if (wrqu->data.length < length)
+ {
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
+ return -EFAULT;
+ }
+ vos_mem_copy( extra, (v_VOID_t*)genIeBytes, wrqu->data.length);
+ wrqu->data.length = length;
hddLog(LOG1,"%s: RSN IE of %d bytes returned\n", __func__, wrqu->data.length );
@@ -2220,7 +2224,7 @@ static int iw_get_rssi(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- char *cmd = (char*)wrqu->data.pointer;
+ char *cmd = extra;
int len = wrqu->data.length;
v_S7_t s7Rssi = 0;
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
@@ -2477,7 +2481,7 @@ static int iw_set_priv(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- char *cmd = (char*)wrqu->data.pointer;
+ char *cmd = extra;
int cmd_len = wrqu->data.length;
int ret = 0;
int status = 0;
@@ -2731,6 +2735,16 @@ done:
/* there was an encoding error or overflow */
status = -EIO;
}
+ else if (ret > 0)
+ {
+ if (copy_to_user(wrqu->data.pointer, cmd, ret))
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: failed to copy data to user buffer", __func__);
+ return -EFAULT;
+ }
+ wrqu->data.length = ret;
+ }
if (ioctl_debug)
{
@@ -2738,7 +2752,6 @@ done:
__func__, cmd, wrqu->data.length, status);
}
return status;
-
}
static int iw_set_nick(struct net_device *dev,
@@ -3683,7 +3696,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
#endif /* WLAN_FEATURE_VOWIFI */
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received length %d", __func__, wrqu->data.length);
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __func__, (char*)wrqu->data.pointer);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __func__, extra);
if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
{
@@ -3696,11 +3709,11 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
{
case WE_WOWL_ADD_PTRN:
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN\n");
- hdd_add_wowl_ptrn(pAdapter, (char*)wrqu->data.pointer);
+ hdd_add_wowl_ptrn(pAdapter, extra);
break;
case WE_WOWL_DEL_PTRN:
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN\n");
- hdd_del_wowl_ptrn(pAdapter, (char*)wrqu->data.pointer);
+ hdd_del_wowl_ptrn(pAdapter, extra);
break;
#if defined WLAN_FEATURE_VOWIFI
case WE_NEIGHBOR_REPORT_REQUEST:
@@ -3715,7 +3728,7 @@ static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *in
if( !neighborReq.no_ssid )
{
neighborReq.ssid.length = (wrqu->data.length - 1) > 32 ? 32 : (wrqu->data.length - 1) ;
- vos_mem_copy( neighborReq.ssid.ssId, wrqu->data.pointer, neighborReq.ssid.length );
+ vos_mem_copy( neighborReq.ssid.ssId, extra, neighborReq.ssid.length );
}
callbackInfo.neighborRspCallback = NULL;
@@ -3733,10 +3746,10 @@ 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), wrqu->data.pointer, wrqu->data.length );
+ sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), extra, wrqu->data.length );
break;
case WE_SET_CONFIG:
- vstatus = hdd_execute_config_command(pHddCtx, wrqu->data.pointer);
+ vstatus = hdd_execute_config_command(pHddCtx, extra);
if (VOS_STATUS_SUCCESS != vstatus)
{
ret = -EINVAL;
@@ -4244,7 +4257,7 @@ int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
int sub_cmd = wrqu->data.flags;
- int *value = (int*)wrqu->data.pointer;
+ int *value = (int*)extra;
int apps_args[MAX_VAR_ARGS] = {0};
int num_args = wrqu->data.length;
hdd_station_ctx_t *pStaCtx = NULL ;
@@ -4595,10 +4608,10 @@ static int iw_qcom_set_wapi_mode(struct net_device *dev, struct iw_request_info
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
- WAPI_FUNCTION_MODE *pWapiMode = (WAPI_FUNCTION_MODE *)wrqu->data.pointer;
+ WAPI_FUNCTION_MODE *pWapiMode = (WAPI_FUNCTION_MODE *)extra;
hddLog(LOG1, "The function iw_qcom_set_wapi_mode called");
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)wrqu->data.pointer);
+ hddLog(LOG1, "%s: Received data %s", __func__, extra);
hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
hddLog(LOG1, "%s: Input Data (wreq) WAPI Mode:%02d", __func__, pWapiMode->wapiMode);
@@ -4661,7 +4674,6 @@ static int iw_qcom_set_wapi_assoc_info(struct net_device *dev, struct iw_request
int i = 0, j = 0;
hddLog(LOG1, "The function iw_qcom_set_wapi_assoc_info called");
hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)wrqu->data.pointer);
hddLog(LOG1, "%s: Received data %s", __func__, (char*)extra);
if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
@@ -4727,7 +4739,6 @@ static int iw_qcom_set_wapi_key(struct net_device *dev, struct iw_request_info *
hddLog(LOG1, "The function iw_qcom_set_wapi_key called ");
hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)wrqu->data.pointer);
hddLog(LOG1, "%s: Received data %s", __func__, (char*)extra);
hddLog(LOG1,":s: INPUT DATA:\nKey Type:0x%02x Key Direction:0x%02x KEY ID:0x%02x\n", __func__,pWapiKey->keyType,pWapiKey->keyDirection,pWapiKey->keyId);
@@ -4828,12 +4839,11 @@ static int iw_qcom_set_wapi_bkid(struct net_device *dev, struct iw_request_info
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
#ifdef WLAN_DEBUG
int i = 0;
- WLAN_BKID_LIST *pBkid = ( WLAN_BKID_LIST *) (wrqu->data.pointer);
+ WLAN_BKID_LIST *pBkid = ( WLAN_BKID_LIST *) extra;
#endif
hddLog(LOG1, "The function iw_qcom_set_wapi_bkid called");
hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length);
- hddLog(LOG1, "%s: Received data %s", __func__, (char*)wrqu->data.pointer);
hddLog(LOG1, "%s: Received data %s", __func__, (char*)extra);
hddLog(LOG1,"%s: INPUT DATA:\n BKID Length:0x%08lx\n", __func__,pBkid->length);
@@ -4910,7 +4920,7 @@ static int iw_set_fties(struct net_device *dev, struct iw_request_info *info,
#endif
// Pass the received FT IEs to SME
- sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, wrqu->data.pointer,
+ sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, extra,
wrqu->data.length);
return 0;
@@ -4922,7 +4932,7 @@ static int iw_set_dynamic_mcbc_filter(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpRcvFltMcAddrList pRequest = (tpRcvFltMcAddrList)wrqu->data.pointer;
+ tpRcvFltMcAddrList pRequest = (tpRcvFltMcAddrList)extra;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
tpSirWlanSetRxpFilters wlanRxpFilterParam;
tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
@@ -5067,7 +5077,7 @@ static int iw_set_host_offload(struct net_device *dev, struct iw_request_info *i
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpHostOffloadRequest pRequest = (tpHostOffloadRequest)wrqu->data.pointer;
+ tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
tSirHostOffloadReq offloadRequest;
if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
@@ -5076,7 +5086,6 @@ static int iw_set_host_offload(struct net_device *dev, struct iw_request_info *i
"%s:LOGP in Progress. Ignore!!!", __func__);
return -EBUSY;
}
-
/* Debug display of request components. */
switch (pRequest->offloadType)
{
@@ -5139,7 +5148,7 @@ static int iw_set_keepalive_params(struct net_device *dev, struct iw_request_inf
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpKeepAliveRequest pRequest = (tpKeepAliveRequest)wrqu->data.pointer;
+ tpKeepAliveRequest pRequest = (tpKeepAliveRequest) extra;
tSirKeepAliveReq keepaliveRequest;
if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
@@ -5340,7 +5349,7 @@ static int iw_set_packet_filter_params(struct net_device *dev, struct iw_request
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tpPacketFilterCfg pRequest = (tpPacketFilterCfg)wrqu->data.pointer;
+ tpPacketFilterCfg pRequest = (tpPacketFilterCfg) extra;
return wlan_hdd_set_filter(WLAN_HDD_GET_CTX(pAdapter), pRequest, pAdapter->sessionId);
}
@@ -5573,7 +5582,7 @@ VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info,
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"PNO data len %d data %s",
wrqu->data.length,
- wrqu->data.pointer);
+ extra);
if (wrqu->data.length <= nOffset )
{
@@ -5611,7 +5620,7 @@ VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info,
scan every 5 seconds 2 times, scan every 300 seconds until stopped
-----------------------------------------------------------------------*/
- ptr = (char*)(wrqu->data.pointer + nOffset);
+ ptr = extra + nOffset;
sscanf(ptr,"%hhu%n", &(pnoRequest.enable), &nOffset);
@@ -5822,7 +5831,7 @@ VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *in
v_U8_t rssiThreshold = 0;
v_U8_t nRead;
- nRead = sscanf(wrqu->data.pointer + nOffset,"%hhu",
+ nRead = sscanf(extra + nOffset,"%hhu",
&rssiThreshold);
if ( 1 != nRead )
@@ -5983,7 +5992,7 @@ static int iw_set_band_config(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
- tANI_U8 *ptr = (tANI_U8*)wrqu->data.pointer;
+ tANI_U8 *ptr = extra;
int ret = 0;
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: ", __func__);
@@ -6030,7 +6039,7 @@ VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *i
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"Power Params data len %d data %s",
wrqu->data.length,
- wrqu->data.pointer);
+ extra);
if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
{
@@ -6072,7 +6081,7 @@ VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *i
powerRequest.uEnableBET = SIR_NOCHANGE_POWER_VALUE;
powerRequest.uBETInterval = SIR_NOCHANGE_POWER_VALUE;
- ptr = (char*)(wrqu->data.pointer + nOffset);
+ ptr = extra + nOffset;
while ( uTotalSize )
{
--
cgit v1.1