Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8195dd6 authored by Jianmin Zhu's avatar Jianmin Zhu Committed by Gerrit - the friendly Code Review server
Browse files

qcacld-3.0: Fix array OOB for duplicate rate

Some IoT AP may have duplicate rates in supported rates and
extended rates in beacon, need filter them when populate peer 11a/11b
rates during connect/roaming, or array out of bound issue will happen.

Change-Id: I685e8c07ee147296bfa22742dad4210e7fa02c4a
CRs-Fixed: 3048142
parent 28f22260
Loading
Loading
Loading
Loading
+47 −45
Original line number Diff line number Diff line
/*
 * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
@@ -1653,9 +1653,9 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac,
{
	tSirMacRateSet tempRateSet;
	tSirMacRateSet tempRateSet2;
	uint32_t i, j, val, min, isArate;

	isArate = 0;
	uint32_t i, j, val, min, isArate = 0;
	uint8_t aRateIndex = 0;
	uint8_t bRateIndex = 0;

	/* copy operational rate set from psessionEntry */
	if (psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX) {
@@ -1700,52 +1700,54 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac,
	 * Sort rates in tempRateSet (they are likely to be already sorted)
	 * put the result in pSupportedRates
	 */
	{
		uint8_t aRateIndex = 0;
		uint8_t bRateIndex = 0;

		qdf_mem_set((uint8_t *) pRates, sizeof(tSirSupportedRates), 0);
	qdf_mem_zero(pRates, sizeof(*pRates));
	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++) {
		for (j = 0; (j < tempRateSet.numRates) &&
		     (j < SIR_MAC_MAX_NUMBER_OF_RATES); j++) {
			if ((uint32_t)(tempRateSet.rate[j] & 0x7f) <
					val) {
				val = tempRateSet.rate[j] & 0x7f;
				min = j;
			}
		}
			if (sirIsArate(tempRateSet.rate[min] & 0x7f))
		if (sirIsArate(tempRateSet.rate[min] & 0x7f)) {
			isArate = 1;
		} else if (sirIsBrate(tempRateSet.rate[min] & 0x7f)) {
			isArate = 0;
		} else {
			pe_debug("%d is neither 11a nor 11b rate",
				 tempRateSet.rate[min]);
			tempRateSet.rate[min] = 0xff;
			continue;
		}
		if (tempRateSet.rate[min] == pRates->llaRates[aRateIndex] ||
		    tempRateSet.rate[min] == pRates->llbRates[bRateIndex]) {
			pe_debug("Duplicate rate: %d", tempRateSet.rate[min]);
			tempRateSet.rate[min] = 0xff;
			continue;
		}
		/*
			 * 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.
		 * 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];
		if (basicOnly && !(tempRateSet.rate[min] & 0x80)) {
			tempRateSet.rate[min] = 0xff;
			continue;
		}
			} else {
				if (isArate)
		if (isArate && aRateIndex < SIR_NUM_11A_RATES)
			pRates->llaRates[aRateIndex++] =
					tempRateSet.rate[min];
				else
		else if (bRateIndex < SIR_NUM_11B_RATES)
			pRates->llbRates[bRateIndex++] =
					tempRateSet.rate[min];
			}
		tempRateSet.rate[min] = 0xff;
	}
	}

	if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
		val = SIZE_OF_SUPPORTED_MCS_SET;