mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
337 lines
13 KiB
Diff
337 lines
13 KiB
Diff
From 28d4f0c1f712bffb4aa5b47f06e97d5a9fa06d29 Mon Sep 17 00:00:00 2001
|
|
From: Arif Hussain <c_arifh@qca.qualcomm.com>
|
|
Date: Sun, 27 Oct 2013 23:01:14 -0700
|
|
Subject: wlan: Userspace data copy fix
|
|
|
|
Use copy_to_user and copy_from_user for
|
|
copying data to/from user space.
|
|
|
|
Change-Id: I07ed5361b439f4bcd61bbf693cc17c950f5b2660
|
|
CRs-Fixed: 561022
|
|
---
|
|
CORE/HDD/inc/wlan_hdd_main.h | 1 +
|
|
CORE/HDD/src/wlan_hdd_hostapd.c | 160 ++++++++++++++++++++++++++++++----------
|
|
2 files changed, 124 insertions(+), 37 deletions(-)
|
|
|
|
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
|
|
index 57b2ec0..e3fcca4 100644
|
|
--- a/CORE/HDD/inc/wlan_hdd_main.h
|
|
+++ b/CORE/HDD/inc/wlan_hdd_main.h
|
|
@@ -153,6 +153,7 @@
|
|
#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
|
/** Mac Address string **/
|
|
#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
|
+#define MAC_ADDRESS_STR_LEN 18 /* Including null terminator */
|
|
#define MAX_GENIE_LEN 255
|
|
|
|
#define WLAN_CHIP_VERSION "WCNSS"
|
|
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
|
|
index a5d696e..a155932 100644
|
|
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
|
|
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
|
|
@@ -1418,12 +1418,13 @@ static iw_softap_getassoc_stamacaddr(struct net_device *dev,
|
|
union iwreq_data *wrqu, char *extra)
|
|
{
|
|
hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
|
|
- unsigned char *pmaclist;
|
|
+ unsigned int maclist_index;
|
|
hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
|
|
+ char maclist_null = '\0';
|
|
int cnt = 0, len;
|
|
|
|
|
|
- pmaclist = wrqu->data.pointer + sizeof(unsigned long int);
|
|
+ maclist_index = sizeof(unsigned long int);
|
|
len = wrqu->data.length;
|
|
|
|
spin_lock_bh( &pHostapdAdapter->staInfo_lock );
|
|
@@ -1431,8 +1432,13 @@ static iw_softap_getassoc_stamacaddr(struct net_device *dev,
|
|
if (TRUE == pStaInfo[cnt].isUsed) {
|
|
|
|
if(!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes)) {
|
|
- memcpy((void *)pmaclist, (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t));
|
|
- pmaclist += sizeof(v_MACADDR_t);
|
|
+ if (copy_to_user((void *)wrqu->data.pointer + maclist_index,
|
|
+ (void *)&(pStaInfo[cnt].macAddrSTA), sizeof(v_MACADDR_t)))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+ maclist_index += sizeof(v_MACADDR_t);
|
|
len -= sizeof(v_MACADDR_t);
|
|
}
|
|
}
|
|
@@ -1440,12 +1446,16 @@ static iw_softap_getassoc_stamacaddr(struct net_device *dev,
|
|
}
|
|
spin_unlock_bh( &pHostapdAdapter->staInfo_lock );
|
|
|
|
- *pmaclist = '\0';
|
|
-
|
|
+ if (copy_to_user((void *)wrqu->data.pointer + maclist_index,
|
|
+ (void *)&maclist_null, sizeof(maclist_null)) ||
|
|
+ copy_to_user((void *)wrqu->data.pointer,
|
|
+ (void *)&wrqu->data.length, sizeof(wrqu->data.length)))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ return -EFAULT;
|
|
+ }
|
|
wrqu->data.length -= len;
|
|
|
|
- *(unsigned long int *)(wrqu->data.pointer) = wrqu->data.length;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -1494,20 +1504,35 @@ static iw_softap_ap_stats(struct net_device *dev,
|
|
int len = wrqu->data.length;
|
|
pstatbuf = wrqu->data.pointer;
|
|
|
|
- WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &statBuffer, (v_BOOL_t)wrqu->data.flags);
|
|
-
|
|
- len = scnprintf(pstatbuf, len,
|
|
- "RUF=%d RMF=%d RBF=%d "
|
|
- "RUB=%d RMB=%d RBB=%d "
|
|
- "TUF=%d TMF=%d TBF=%d "
|
|
- "TUB=%d TMB=%d TBB=%d",
|
|
- (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, (int)statBuffer.rxBCFcnt,
|
|
- (int)statBuffer.rxUCBcnt, (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
|
|
- (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, (int)statBuffer.txBCFcnt,
|
|
- (int)statBuffer.txUCBcnt, (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt
|
|
- );
|
|
+ WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext,
|
|
+ &statBuffer, (v_BOOL_t)wrqu->data.flags);
|
|
|
|
+ pstatbuf = kmalloc(wrqu->data.length, GFP_KERNEL);
|
|
+ if(NULL == pstatbuf) {
|
|
+ hddLog(LOG1, "unable to allocate memory");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ len = scnprintf(pstatbuf, wrqu->data.length,
|
|
+ "RUF=%d RMF=%d RBF=%d "
|
|
+ "RUB=%d RMB=%d RBB=%d "
|
|
+ "TUF=%d TMF=%d TBF=%d "
|
|
+ "TUB=%d TMB=%d TBB=%d",
|
|
+ (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt,
|
|
+ (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt,
|
|
+ (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt,
|
|
+ (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt,
|
|
+ (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt,
|
|
+ (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt);
|
|
+
|
|
+ if (len > wrqu->data.length ||
|
|
+ copy_to_user((void *)wrqu->data.pointer, (void *)pstatbuf, len))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ kfree(pstatbuf);
|
|
+ return -EFAULT;
|
|
+ }
|
|
wrqu->data.length -= len;
|
|
+ kfree(pstatbuf);
|
|
return 0;
|
|
}
|
|
|
|
@@ -1870,8 +1895,15 @@ int iw_get_genie(struct net_device *dev,
|
|
status = WLANSap_getstationIE_information(pVosContext,
|
|
&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 ||
|
|
+ copy_to_user(wrqu->data.pointer,
|
|
+ (v_VOID_t*)genIeBytes, length))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+ wrqu->data.length = length;
|
|
|
|
hddLog(LOG1,FL(" RSN IE of %d bytes returned\n"), wrqu->data.length );
|
|
|
|
@@ -1885,18 +1917,30 @@ int iw_get_WPSPBCProbeReqIEs(struct net_device *dev,
|
|
union iwreq_data *wrqu, char *extra)
|
|
{
|
|
hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
|
|
- sQcSapreq_WPSPBCProbeReqIES_t *pWPSPBCProbeReqIEs;
|
|
+ sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
|
|
hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
|
|
ENTER();
|
|
-
|
|
+
|
|
hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl\n"));
|
|
-
|
|
- pWPSPBCProbeReqIEs = (sQcSapreq_WPSPBCProbeReqIES_t *)(wrqu->data.pointer);
|
|
- pWPSPBCProbeReqIEs->probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
|
|
- vos_mem_copy(pWPSPBCProbeReqIEs->probeReqIE, pHddApCtx->WPSPBCProbeReq.probeReqIE, pWPSPBCProbeReqIEs->probeReqIELen);
|
|
- vos_mem_copy(pWPSPBCProbeReqIEs->macaddr, pHddApCtx->WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t));
|
|
- wrqu->data.length = 12 + pWPSPBCProbeReqIEs->probeReqIELen;
|
|
- hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR"\n"), MAC_ADDR_ARRAY(pWPSPBCProbeReqIEs->macaddr));
|
|
+ memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
|
|
+
|
|
+ WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen;
|
|
+ vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
|
|
+ pHddApCtx->WPSPBCProbeReq.probeReqIE,
|
|
+ WPSPBCProbeReqIEs.probeReqIELen);
|
|
+ vos_mem_copy(&WPSPBCProbeReqIEs.macaddr,
|
|
+ pHddApCtx->WPSPBCProbeReq.peerMacAddr,
|
|
+ sizeof(v_MACADDR_t));
|
|
+ if (copy_to_user(wrqu->data.pointer,
|
|
+ (void *)&WPSPBCProbeReqIEs,
|
|
+ sizeof(WPSPBCProbeReqIEs)))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+ wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
|
|
+ hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR"\n"),
|
|
+ MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
|
|
up(&pHddApCtx->semWpsPBCOverlapInd);
|
|
EXIT();
|
|
return 0;
|
|
@@ -2282,20 +2326,37 @@ static int iw_softap_setwpsie(struct net_device *dev,
|
|
v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
|
|
hdd_hostapd_state_t *pHostapdState;
|
|
eHalStatus halStatus= eHAL_STATUS_SUCCESS;
|
|
- u_int8_t *wps_genie = wrqu->data.pointer;
|
|
+ u_int8_t *wps_genie;
|
|
+ u_int8_t *fwps_genie;
|
|
u_int8_t *pos;
|
|
tpSap_WPSIE pSap_WPSIe;
|
|
u_int8_t WPSIeType;
|
|
u_int16_t length;
|
|
ENTER();
|
|
|
|
- if(!wrqu->data.length)
|
|
+ if(!wrqu->data.length || wrqu->data.length <= QCSAP_MAX_WSC_IE)
|
|
return 0;
|
|
|
|
+ wps_genie = kmalloc(wrqu->data.length, GFP_KERNEL);
|
|
+
|
|
+ if(NULL == wps_genie) {
|
|
+ hddLog(LOG1, "unable to allocate memory");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ fwps_genie = wps_genie;
|
|
+ if (copy_from_user((void *)wps_genie,
|
|
+ wrqu->data.pointer, wrqu->data.length))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ kfree(fwps_genie);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+
|
|
pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
|
|
if (NULL == pSap_WPSIe)
|
|
{
|
|
hddLog(LOGE, "VOS unable to allocate memory\n");
|
|
+ kfree(fwps_genie);
|
|
return -ENOMEM;
|
|
}
|
|
vos_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
|
|
@@ -2312,6 +2373,7 @@ static int iw_softap_setwpsie(struct net_device *dev,
|
|
if (wps_genie[1] < 2 + 4)
|
|
{
|
|
vos_mem_free(pSap_WPSIe);
|
|
+ kfree(fwps_genie);
|
|
return -EINVAL;
|
|
}
|
|
else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
|
|
@@ -2385,6 +2447,7 @@ static int iw_softap_setwpsie(struct net_device *dev,
|
|
default:
|
|
hddLog (LOGW, "UNKNOWN TLV in WPS IE(%x)\n", (*pos<<8 | *(pos+1)));
|
|
vos_mem_free(pSap_WPSIe);
|
|
+ kfree(fwps_genie);
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
@@ -2398,6 +2461,7 @@ static int iw_softap_setwpsie(struct net_device *dev,
|
|
default:
|
|
hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, wps_genie[0]);
|
|
vos_mem_free(pSap_WPSIe);
|
|
+ kfree(fwps_genie);
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -2411,6 +2475,7 @@ static int iw_softap_setwpsie(struct net_device *dev,
|
|
if (wps_genie[1] < 2 + 4)
|
|
{
|
|
vos_mem_free(pSap_WPSIe);
|
|
+ kfree(fwps_genie);
|
|
return -EINVAL;
|
|
}
|
|
else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4) == 0)
|
|
@@ -2575,6 +2640,7 @@ static int iw_softap_setwpsie(struct net_device *dev,
|
|
}
|
|
|
|
vos_mem_free(pSap_WPSIe);
|
|
+ kfree(fwps_genie);
|
|
EXIT();
|
|
return halStatus;
|
|
}
|
|
@@ -2682,7 +2748,7 @@ static int iw_set_ap_genie(struct net_device *dev,
|
|
hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
|
|
v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
|
|
eHalStatus halStatus= eHAL_STATUS_SUCCESS;
|
|
- u_int8_t *genie = wrqu->data.pointer;
|
|
+ u_int8_t *genie = (u_int8_t *)extra;
|
|
|
|
ENTER();
|
|
|
|
@@ -2691,7 +2757,7 @@ static int iw_set_ap_genie(struct net_device *dev,
|
|
EXIT();
|
|
return 0;
|
|
}
|
|
-
|
|
+
|
|
switch (genie[0])
|
|
{
|
|
case DOT11F_EID_WPA:
|
|
@@ -2702,7 +2768,7 @@ static int iw_set_ap_genie(struct net_device *dev,
|
|
hdd_softap_Register_BC_STA(pHostapdAdapter, 1);
|
|
}
|
|
(WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
|
|
- halStatus = WLANSAP_Set_WPARSNIes(pVosContext, wrqu->data.pointer, wrqu->data.length);
|
|
+ halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length);
|
|
break;
|
|
|
|
default:
|
|
@@ -2768,6 +2834,7 @@ int iw_get_softap_linkspeed(struct net_device *dev,
|
|
hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
|
|
hdd_context_t *pHddCtx;
|
|
char *pLinkSpeed = (char*)extra;
|
|
+ char *pmacAddress;
|
|
v_U32_t link_speed;
|
|
unsigned short staId;
|
|
int len = sizeof(v_U32_t)+1;
|
|
@@ -2786,7 +2853,26 @@ int iw_get_softap_linkspeed(struct net_device *dev,
|
|
}
|
|
|
|
hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d\n", __func__, wrqu->data.length);
|
|
- status = hdd_string_to_hex ((char *)wrqu->data.pointer, wrqu->data.length, macAddress );
|
|
+ if (wrqu->data.length != MAC_ADDRESS_STR_LEN)
|
|
+ {
|
|
+ hddLog(LOG1, "Invalid length");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL);
|
|
+ if(NULL == pmacAddress) {
|
|
+ hddLog(LOG1, "unable to allocate memory");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ if (copy_from_user((void *)pmacAddress,
|
|
+ wrqu->data.pointer, wrqu->data.length))
|
|
+ {
|
|
+ hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
|
|
+ kfree(pmacAddress);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+
|
|
+ status = hdd_string_to_hex (pmacAddress, wrqu->data.length, macAddress );
|
|
+ kfree(pmacAddress);
|
|
|
|
if (!VOS_IS_STATUS_SUCCESS(status ))
|
|
{
|
|
--
|
|
cgit v1.1
|
|
|