Merge "wlan: Fix FT roaming failure issue " into wlan-driver.lnx.1.0
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index c2db0a5..bf364ee 100644
--- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -1359,16 +1359,6 @@
     val = 0;
     val1 = 0;
 
-    pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid,
-                              &psessionEntry->dph.dphHashTable);
-    if (((psessionEntry->limSystemRole == eLIM_AP_ROLE ||
-          psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) &&
-         pSta != NULL && !pSta->isKeyInstalled) ||
-        !psessionEntry->isKeyInstalled) {
-        limLog(pMac, LOGE, FL("Reject ADDBA as set_key is not done"));
-        return;
-    }
-
     // Unpack the received frame
     nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq );
     if( DOT11F_FAILED( nStatus ))
@@ -1395,6 +1385,8 @@
 
     psessionEntry->amsduSupportedInBA = frmAddBAReq.AddBAParameterSet.amsduSupported;
 
+    pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid,
+                              &psessionEntry->dph.dphHashTable);
     if( pSta == NULL )
     {
         limLog( pMac, LOGE,
diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.c b/CORE/MAC/src/pe/lim/limScanResultUtils.c
index f166ec7..5d1017f 100644
--- a/CORE/MAC/src/pe/lim/limScanResultUtils.c
+++ b/CORE/MAC/src/pe/lim/limScanResultUtils.c
@@ -709,7 +709,7 @@
     tANI_U8                found = false;
     tLimScanResultNode *ptemp, *pprev;
     tSirMacCapabilityInfo *pSirCap, *pSirCapTemp;
-    int idx, len;
+    int len, elem_id, elem_len;
     tANI_U8 *pbIe;
     tANI_S8  rssi = 0;
 
@@ -757,31 +757,44 @@
                    rssi = ptemp->bssDescription.rssi;
                 }
 
-                if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp)
+                if(pBssDescr->bssDescription.fProbeRsp !=
+                                             ptemp->bssDescription.fProbeRsp)
                 {
                     //We get a different, save the old frame WSC IE if it is there
-                    idx = 0;
-                    len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + 
-                       sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
+                    len = ptemp->bssDescription.length -
+                                 sizeof(tSirBssDescription) +
+                                 sizeof(tANI_U16) + sizeof(tANI_U32);
                     pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields;
                     //Save WPS IE if it exists
                     pBssDescr->bssDescription.WscIeLen = 0;
-                    while(idx < len)
+                    while (len >= 2)
                     {
-                        if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
-                           (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
+                        elem_id = pbIe[0];
+                        elem_len = pbIe[1];
+                        len -= 2;
+                        if (elem_len > len) {
+                            limLog(pMac, LOGW, FL("Invalid eid: %d elem_len: %d left: %d"),
+                                   elem_id, elem_len, len);
+                            return eHAL_STATUS_FAILURE;
+                        }
+                        if ((elem_id == DOT11F_EID_WSCPROBERES) &&
+                            (elem_len >= DOT11F_IE_WSCPROBERES_MIN_LEN) &&
+                            ((pbIe[2] == 0x00) && (pbIe[3] == 0x50) &&
+                             (pbIe[4] == 0xf2) &&
+                             (pbIe[5] == 0x04)))
                         {
-                            //Found it
-                            if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
+                            if((elem_len + 2) <= WSCIE_PROBE_RSP_LEN)
                             {
-                                vos_mem_copy(pBssDescr->bssDescription.WscIeProbeRsp,
-                                   pbIe, pbIe[1] + 2);
-                                pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2;
+                                vos_mem_copy(
+                                        pBssDescr->bssDescription.WscIeProbeRsp,
+                                        pbIe, elem_len + 2);
+                                pBssDescr->bssDescription.WscIeLen =
+                                                          elem_len + 2;
                             }
                             break;
                         }
-                        idx += pbIe[1] + 2;
-                        pbIe += pbIe[1] + 2;
+                        len -= elem_len;
+                        pbIe += (elem_len + 2);
                     }
                 }
                 /*
diff --git a/CORE/SME/src/QoS/sme_Qos.c b/CORE/SME/src/QoS/sme_Qos.c
index 3b01d8e..bfbed73 100644
--- a/CORE/SME/src/QoS/sme_Qos.c
+++ b/CORE/SME/src/QoS/sme_Qos.c
@@ -3147,7 +3147,7 @@
     tspecIeLen = pCsrConnectedInfo->nTspecIeLength;
     if (tspecIeLen < sizeof(tDot11fIEWMMTSPEC)) {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
-                FL("ESE Tspec IE len %d less than min %d"),
+                FL("ESE Tspec IE len %d less than min %zu"),
                 tspecIeLen, sizeof(tDot11fIEWMMTSPEC));
         return eHAL_STATUS_FAILURE;
     }
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index 7fa02d5..4fe6095 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -3390,38 +3390,44 @@
     return (status);
 }
 
-
-
-void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr, tSirBssDescription *pOldBssDescr)
+void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr,tSirBssDescription *pOldBssDescr)
 {
-    int idx, len;
+    int elem_id, len, elem_len;
     tANI_U8 *pbIe;
 
     //If failed to remove, assuming someone else got it.
     if((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) &&
        (0 == pNewBssDescr->WscIeLen))
     {
-        idx = 0;
-        len = GET_IE_LEN_IN_BSS(pOldBssDescr->length)
-              - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
+        len = GET_IE_LEN_IN_BSS(pOldBssDescr->length);
         pbIe = (tANI_U8 *)pOldBssDescr->ieFields;
         //Save WPS IE if it exists
         pNewBssDescr->WscIeLen = 0;
-        while(idx < len)
+        while (len >= 2)
         {
-            if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
-                (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
-            {
-                //Founrd it
-                if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
-                {
-                    vos_mem_copy(pNewBssDescr->WscIeProbeRsp, pbIe, pbIe[1] + 2);
-                    pNewBssDescr->WscIeLen = pbIe[1] + 2;
-                }
-                break;
+            elem_id = pbIe[0];
+            elem_len = pbIe[1];
+            len -= 2;
+            if (elem_len > len) {
+                smsLog(pMac, LOGW, FL("Invalid eid: %d elem_len: %d left: %d"),
+                       elem_id, elem_len, len);
+                return;
             }
-            idx += pbIe[1] + 2;
-            pbIe += pbIe[1] + 2;
+            if ((elem_id == DOT11F_EID_WSCPROBERES) &&
+                (elem_len >= DOT11F_IE_WSCPROBERES_MIN_LEN) &&
+                ((pbIe[2] == 0x00) && (pbIe[3] == 0x50) && (pbIe[4] == 0xf2) &&
+                (pbIe[5] == 0x04)))
+            {
+                if((elem_len + 2) <= WSCIE_PROBE_RSP_LEN)
+                {
+                    vos_mem_copy(pNewBssDescr->WscIeProbeRsp,
+                                 pbIe, elem_len + 2);
+                    pNewBssDescr->WscIeLen = elem_len + 2;
+                }
+                return;
+            }
+            len -= elem_len;
+            pbIe += (elem_len + 2);
         }
     }
 }
diff --git a/CORE/SVC/src/btc/wlan_btc_svc.c b/CORE/SVC/src/btc/wlan_btc_svc.c
index f64605d..489544b 100644
--- a/CORE/SVC/src/btc/wlan_btc_svc.c
+++ b/CORE/SVC/src/btc/wlan_btc_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -56,12 +56,14 @@
    struct nlmsghdr *nlh;
    tAniMsgHdr *aniHdr;
    tWlanAssocData *assocData;
-   skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
+   uint32_t skb_size = NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD);
+   skb = alloc_skb(skb_size, GFP_KERNEL);
    if(skb == NULL) {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
          "BTC: alloc_skb failed\n");
       return;
    }   
+   vos_mem_zero(skb->data, skb_size);
    nlh = (struct nlmsghdr *)skb->data;
    nlh->nlmsg_pid = 0;  /* from kernel */
    nlh->nlmsg_flags = 0;