DroidSec:Unsafe access to user space memory from kernel

function iw_ftm_setchar_getnone in wlan_hdd_ftm.c
improperly use wrqu->data.pointer to access user space memory:
1.data.pointer dereferenced as string in VOS_TRACE
2.passes data.pointer into wlan_ftm_priv_set_mac_address() referenced
  as a string containing MAC address
3.passes data.pointer into wlan_ftm_priv_set_txrate() compared to
  rateName_rateIndex_tbl[ii].rate_str (read from user space)

Change-Id: I07ae60dbe154212afe0b087f2c3a060f581baedc
CRs-fixed: 561019
diff --git a/CORE/HDD/src/wlan_hdd_ftm.c b/CORE/HDD/src/wlan_hdd_ftm.c
index 4d50e79..736c96f 100644
--- a/CORE/HDD/src/wlan_hdd_ftm.c
+++ b/CORE/HDD/src/wlan_hdd_ftm.c
@@ -4257,26 +4257,44 @@
 static int iw_ftm_setchar_getnone(struct net_device *dev, struct iw_request_info *info,
                        union iwreq_data *wrqu, char *extra)
 {
-    int sub_cmd = wrqu->data.flags;
-    int ret = 0; /* success */
+    int ret,sub_cmd;
+    unsigned int length;
     VOS_STATUS status;
-    hdd_adapter_t *pAdapter = (netdev_priv(dev));
+    hdd_adapter_t *pAdapter;
 
-    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);
+    ret =0;
+    length = wrqu->data.length;
+    sub_cmd = wrqu->data.flags;
+    pAdapter = (hdd_adapter_t *)netdev_priv(dev);
+
+    /*we can only accept input falling between 1 and length bytes,
+     *and ensure extra is null delimited string
+     */
+    if (wrqu->data.length>=512)
+        return -EINVAL;
+    vos_mem_zero(extra + length,512 - length);
+
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+              "%s: Received length %d", __func__, length);
+
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+              "%s: Received data %s", __func__, extra);
 
     switch(sub_cmd)
     {
        case WE_SET_MAC_ADDRESS:
        {
 
-          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "SET MAC ADDRESS\n");
+          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                    "SET MAC ADDRESS\n");
 
-          status  = wlan_ftm_priv_set_mac_address(pAdapter,(char*)wrqu->data.pointer);
+          status  = wlan_ftm_priv_set_mac_address(pAdapter,extra);
 
           if(status != VOS_STATUS_SUCCESS)
           {
-             hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_mac_address Failed =%d\n",status);
+             hddLog(VOS_TRACE_LEVEL_FATAL,
+                    "wlan_ftm_priv_set_mac_address Failed =%d\n",status);
+
              ret = -EINVAL;
           }
 
@@ -4284,12 +4302,14 @@
        break;
        case WE_SET_TX_RATE:
        {
-            status  = wlan_ftm_priv_set_txrate(pAdapter,(char*)wrqu->data.pointer);
+            status  = wlan_ftm_priv_set_txrate(pAdapter,extra);
 
             if(status != VOS_STATUS_SUCCESS)
             {
-               hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_txrate Failed =%d\n",status);
-               ret = -EINVAL;
+               hddLog(VOS_TRACE_LEVEL_FATAL,
+                      "wlan_ftm_priv_set_txrate Failed =%d\n",status);
+
+                ret = -EINVAL;
             }
 
             break;