فهرست منبع

qcacld-3.0: Restrict pcl_len to QDF_MAX_NUM_CHAN

The channel_list array for pcl channels is defined with size
QDF_MAX_NUM_CHAN. The index for the channel_list array can go
beyond QDF_MAX_NUM_CHAN.

The fix is to take care that the index for the channel list
for pcl channels does not exceed QDF_MAX_NUM_CHAN.

Change-Id: I1afd7e4b0ee13e02611cbc5f56a27d1da9ef06a6
CRs-Fixed: 1093129
Nitesh Shah 8 سال پیش
والد
کامیت
3197b711c9
1فایلهای تغییر یافته به همراه43 افزوده شده و 26 حذف شده
  1. 43 26
      core/cds/src/cds_concurrency.c

+ 43 - 26
core/cds/src/cds_concurrency.c

@@ -4488,22 +4488,23 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
 			if (skip_dfs_channel && CDS_IS_DFS_CH(
 				    conc_connection_list[conn_index].chan)) {
 				conn_index++;
-			} else {
+			} else if (*index < weight_len) {
 				channels[num_channels++] =
 					conc_connection_list[conn_index++].chan;
-				if (*index < weight_len)
-					pcl_weight[(*index)++] = weight1;
+				pcl_weight[(*index)++] = weight1;
+			} else {
+				conn_index++;
 			}
 		}
 		*len = num_channels;
 	} else if (CDS_PCL_ORDER_24G_THEN_5G == order) {
 		while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
 			if (CDS_IS_CHANNEL_24GHZ(
-				    conc_connection_list[conn_index].chan)) {
+				    conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
 				channels[num_channels++] =
 					conc_connection_list[conn_index++].chan;
-				if (*index < weight_len)
-					pcl_weight[(*index)++] = weight1;
+				pcl_weight[(*index)++] = weight1;
 			} else {
 				conn_index++;
 			}
@@ -4514,11 +4515,11 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
 				    conc_connection_list[conn_index].chan)) {
 				conn_index++;
 			} else if (CDS_IS_CHANNEL_5GHZ(
-				    conc_connection_list[conn_index].chan)) {
+				    conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
 				channels[num_channels++] =
 					conc_connection_list[conn_index++].chan;
-				if (*index < weight_len)
-					pcl_weight[(*index)++] = weight2;
+				pcl_weight[(*index)++] = weight2;
 			} else {
 				conn_index++;
 			}
@@ -4530,11 +4531,11 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
 				conc_connection_list[conn_index].chan)) {
 				conn_index++;
 			} else if (CDS_IS_CHANNEL_5GHZ(
-				    conc_connection_list[conn_index].chan)) {
+				    conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
 				channels[num_channels++] =
 					conc_connection_list[conn_index++].chan;
-				if (*index < weight_len)
-					pcl_weight[(*index)++] = weight1;
+				pcl_weight[(*index)++] = weight1;
 			} else {
 				conn_index++;
 			}
@@ -4542,11 +4543,11 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
 		conn_index = 0;
 		while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
 			if (CDS_IS_CHANNEL_24GHZ(
-				    conc_connection_list[conn_index].chan)) {
+				    conc_connection_list[conn_index].chan)
+				&& (*index < weight_len)) {
 				channels[num_channels++] =
 					conc_connection_list[conn_index++].chan;
-				if (*index < weight_len)
-					pcl_weight[(*index)++] = weight2;
+				pcl_weight[(*index)++] = weight2;
 
 			} else {
 				conn_index++;
@@ -4664,7 +4665,7 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 				       uint32_t weight_len)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
-	uint32_t num_channels = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+	uint32_t num_channels = 0;
 	uint32_t chan_index = 0, chan_index_24 = 0, chan_index_5 = 0;
 	uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
 	uint8_t channel_list_24[QDF_MAX_NUM_CHAN] = {0};
@@ -4779,18 +4780,20 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 	 */
 	switch (pcl) {
 	case CDS_24G:
+		chan_index_24 = QDF_MIN(chan_index_24, weight_len);
 		qdf_mem_copy(pcl_channels, channel_list_24,
 			chan_index_24);
 		*len = chan_index_24;
-		for (i = 0; ((i < *len) && (i < weight_len)); i++)
+		for (i = 0; i < *len; i++)
 			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;
 	case CDS_5G:
+		chan_index_5 = QDF_MIN(chan_index_5, weight_len);
 		qdf_mem_copy(pcl_channels, channel_list_5,
 			chan_index_5);
 		*len = chan_index_5;
-		for (i = 0; ((i < *len) && (i < weight_len)); i++)
+		for (i = 0; i < *len; i++)
 			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;
@@ -4812,10 +4815,12 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 			CDS_PCL_GROUP_ID1_ID2);
 		qdf_mem_copy(pcl_channels, channel_list, num_channels);
 		*len = num_channels;
+		chan_index_24 = QDF_MIN((num_channels + chan_index_24),
+					weight_len) - num_channels;
 		qdf_mem_copy(&pcl_channels[num_channels],
 			channel_list_24, chan_index_24);
 		*len += chan_index_24;
-		for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++)
+		for (j = 0; j < chan_index_24; i++, j++)
 			pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
 
 		status = QDF_STATUS_SUCCESS;
@@ -4829,19 +4834,22 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 		qdf_mem_copy(pcl_channels, channel_list,
 			num_channels);
 		*len = num_channels;
+		chan_index_5 = QDF_MIN((num_channels + chan_index_5),
+					weight_len) - num_channels;
 		qdf_mem_copy(&pcl_channels[num_channels],
 			channel_list_5, chan_index_5);
 		*len += chan_index_5;
-		for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++)
+		for (j = 0; j < chan_index_5; i++, j++)
 			pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;
 	case CDS_24G_SCC_CH:
 	case CDS_24G_MCC_CH:
+		chan_index_24 = QDF_MIN(chan_index_24, weight_len);
 		qdf_mem_copy(pcl_channels, channel_list_24,
 			chan_index_24);
 		*len = chan_index_24;
-		for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++)
+		for (i = 0; i < chan_index_24; i++)
 			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
 		cds_get_connection_channels(
 			channel_list, &num_channels, CDS_PCL_ORDER_NONE,
@@ -4854,10 +4862,11 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 		break;
 	case CDS_5G_SCC_CH:
 	case CDS_5G_MCC_CH:
+		chan_index_5 = QDF_MIN(chan_index_5, weight_len);
 		qdf_mem_copy(pcl_channels, channel_list_5,
 			chan_index_5);
 		*len = chan_index_5;
-		for (i = 0; ((i < chan_index_5) && (i < weight_len)); i++)
+		for (i = 0; i < chan_index_5; i++)
 			pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
 		cds_get_connection_channels(
 			channel_list, &num_channels, CDS_PCL_ORDER_NONE,
@@ -4894,10 +4903,12 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 			CDS_PCL_GROUP_ID1_ID2);
 		qdf_mem_copy(pcl_channels, channel_list, num_channels);
 		*len = num_channels;
+		chan_index_24 = QDF_MIN((num_channels + chan_index_24),
+					weight_len) - num_channels;
 		qdf_mem_copy(&pcl_channels[num_channels],
 			channel_list_24, chan_index_24);
 		*len += chan_index_24;
-		for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++)
+		for (j = 0; j < chan_index_24; i++, j++)
 			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;
@@ -4908,10 +4919,12 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 			CDS_PCL_GROUP_ID1_ID2);
 		qdf_mem_copy(pcl_channels, channel_list, num_channels);
 		*len = num_channels;
+		chan_index_5 = QDF_MIN((num_channels + chan_index_5),
+					weight_len) - num_channels;
 		qdf_mem_copy(&pcl_channels[num_channels],
 			channel_list_5, chan_index_5);
 		*len += chan_index_5;
-		for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++)
+		for (j = 0; j < chan_index_5; i++, j++)
 			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;
@@ -4922,10 +4935,12 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 			CDS_PCL_GROUP_ID1_ID2);
 		qdf_mem_copy(pcl_channels, channel_list, num_channels);
 		*len = num_channels;
+		chan_index_24 = QDF_MIN((num_channels + chan_index_24),
+					weight_len) - num_channels;
 		qdf_mem_copy(&pcl_channels[num_channels],
 			channel_list_24, chan_index_24);
 		*len += chan_index_24;
-		for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++)
+		for (j = 0; j < chan_index_24; i++, j++)
 			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;
@@ -4936,10 +4951,12 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
 			CDS_PCL_GROUP_ID1_ID2);
 		qdf_mem_copy(pcl_channels, channel_list, num_channels);
 		*len = num_channels;
+		chan_index_5 = QDF_MIN((num_channels + chan_index_5),
+					weight_len) - num_channels;
 		qdf_mem_copy(&pcl_channels[num_channels],
 			channel_list_5, chan_index_5);
 		*len += chan_index_5;
-		for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++)
+		for (j = 0; j < chan_index_5; i++, j++)
 			pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
 		status = QDF_STATUS_SUCCESS;
 		break;