Merge tag 'LA.UM.9.6.2.c26-02500-89xx.0' into int/11/fp3

"LA.UM.9.6.2.c26-02500-89xx.0"

* tag 'LA.UM.9.6.2.c26-02500-89xx.0':
  wlan: Fix array OOB for duplicate rate
  qcacld-2.0: Fix array OOB for duplicate rate
  wlan: Fix possible OOB in UnpackTlvCore
  wlan: Fix possible OOB in unpack_tlv_core
  wlan: Avoid OOB read in dot11f_unpack_assoc_response

Change-Id: I89cdd50061ccc210b60e1666a25c7a4916137234
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c
index 02cf86f..39cf6bf 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.c
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.c
@@ -1785,11 +1785,11 @@
 {
     tSirMacRateSet          tempRateSet;
     tSirMacRateSet          tempRateSet2;
-    tANI_U32                i,j,val,min,isArate;
+    tANI_U32                i,j,val,min;
     tANI_U32 phyMode = 0;
     tANI_U32 selfStaDot11Mode=0;
-
-    isArate = 0;
+    tANI_U8 aRateIndex = 0;
+    tANI_U8 bRateIndex = 0;
 
     wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
     limGetPhyMode(pMac, &phyMode, psessionEntry);
@@ -1839,53 +1839,53 @@
      * Sort rates in tempRateSet (they are likely to be already sorted)
      * put the result in pSupportedRates
      */
-    {
-        tANI_U8 aRateIndex = 0;
-        tANI_U8 bRateIndex = 0;
-
-        vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0);
-        for(i = 0;i < tempRateSet.numRates; i++)
-        {
-            min = 0;
-            val = 0xff;
-            isArate = 0;
-            for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++)
-            {
-                if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
-                {
-                     val = tempRateSet.rate[j] & 0x7f;
-                     min = j;
-                }
+    vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0);
+    for (i = 0; i < tempRateSet.numRates; i++) {
+        min = 0;
+        val = 0xff;
+        for (j = 0; (j < tempRateSet.numRates) &&
+             (j < SIR_MAC_RATESET_EID_MAX); j++) {
+            if ((tANI_U32)(tempRateSet.rate[j] & 0x7f) < val) {
+                val = tempRateSet.rate[j] & 0x7f;
+                min = j;
             }
-
-            if (sirIsArate(tempRateSet.rate[min] & 0x7f))
-                isArate = 1;
-
-    /*
-    * HAL needs to know whether the rate is basic rate or not, as it needs to 
-    * update the response rate table accordingly. e.g. if one of the 11a rates is
-    * basic rate, then that rate can be used for sending control frames.
-    * HAL updates the response rate table whenever basic rate set is changed.
-    */
-            if (basicOnly)
-            {
-                if (tempRateSet.rate[min] & 0x80)
-                {
-                    if (isArate)
-                        pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
-                    else
-                        pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
-                }
-            }
-            else
-            {
-                if (isArate)
-                    pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
-                else
-                    pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
-            }
-            tempRateSet.rate[min] = 0xff;
         }
+        /*
+         * HAL needs to know whether the rate is basic rate or not,
+         * as it needs to update the response rate table accordingly.
+         * e.g. if one of the 11a rates is basic rate, then that rate
+         * can be used for sending control frames. HAL updates the
+         * response rate table whenever basic rate set is changed.
+         */
+        if (basicOnly && !(tempRateSet.rate[min] & 0x80)) {
+            limLog(pMac, LOG2, FL("Invalid basic rate"));
+        } else if (sirIsArate(tempRateSet.rate[min] & 0x7f)) {
+            if (aRateIndex >= SIR_NUM_11A_RATES) {
+                limLog(pMac, LOG2, FL("OOB, aRateIndex: %d"), aRateIndex);
+            } else if (aRateIndex >= 1 && (tempRateSet.rate[min] ==
+                   pRates->llaRates[aRateIndex - 1])) {
+                limLog(pMac, LOG2, FL("Duplicate 11a rate: %d"),
+                       tempRateSet.rate[min]);
+            } else {
+                pRates->llaRates[aRateIndex++] =
+                        tempRateSet.rate[min];
+            }
+        } else if (sirIsBrate(tempRateSet.rate[min] & 0x7f)) {
+            if (bRateIndex >= SIR_NUM_11B_RATES) {
+                limLog(pMac, LOG2, FL("OOB, bRateIndex: %d"), bRateIndex);
+            } else if (bRateIndex >= 1 && (tempRateSet.rate[min] ==
+                   pRates->llbRates[bRateIndex - 1])) {
+                limLog(pMac, LOG2, FL("Duplicate 11b rate: %d"),
+                       tempRateSet.rate[min]);
+            } else {
+                pRates->llbRates[bRateIndex++] =
+                        tempRateSet.rate[min];
+            }
+        } else {
+            limLog(pMac, LOG2, FL("%d is neither 11a nor 11b rate"),
+                   tempRateSet.rate[min]);
+        }
+        tempRateSet.rate[min] = 0xff;
 
     }