Browse Source

qcacld-3.0: Validate total channel stats number from target

In certain case, the hdd_llstats_radio_fill_channels failed to
put more nl attribute for channel stats to upper layer.
Add validation of total channel stats number received from target
to avoid exceeding NUM_CHANNELS. And change error log to include
more debug information.

Change-Id: Ifaf3cf6cd643a3fe87bf7664727da19951f41e93
CRs-Fixed: 2865770
Liangwei Dong 4 years ago
parent
commit
4cdd1268af
2 changed files with 17 additions and 5 deletions
  1. 8 4
      core/hdd/src/wlan_hdd_stats.c
  2. 9 1
      core/wma/src/wma_utils.c

+ 8 - 4
core/hdd/src/wlan_hdd_stats.c

@@ -968,7 +968,7 @@ static int hdd_llstats_radio_fill_channels(struct hdd_adapter *adapter,
 	chlist = nla_nest_start(vendor_event,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
 	if (!chlist) {
-		hdd_err("nla_nest_start failed");
+		hdd_err("nla_nest_start failed, %u", radiostat->num_channels);
 		return -EINVAL;
 	}
 
@@ -979,7 +979,8 @@ static int hdd_llstats_radio_fill_channels(struct hdd_adapter *adapter,
 
 		chinfo = nla_nest_start(vendor_event, i);
 		if (!chinfo) {
-			hdd_err("nla_nest_start failed");
+			hdd_err("nla_nest_start failed, chan number %u",
+				radiostat->num_channels);
 			return -EINVAL;
 		}
 
@@ -1001,7 +1002,9 @@ static int hdd_llstats_radio_fill_channels(struct hdd_adapter *adapter,
 		    nla_put_u32(vendor_event,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
 				channel_stats->cca_busy_time)) {
-			hdd_err("nla_put failed");
+			hdd_err("nla_put failed for channel info (%u, %d, %u)",
+				radiostat->num_channels, i,
+				channel_stats->channel.center_freq);
 			return -EINVAL;
 		}
 
@@ -1015,7 +1018,8 @@ static int hdd_llstats_radio_fill_channels(struct hdd_adapter *adapter,
 				vendor_event,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME,
 				channel_stats->rx_time)) {
-				hdd_err("nla_put failed");
+				hdd_err("nla_put failed for tx time (%u, %d)",
+					radiostat->num_channels, i);
 				return -EINVAL;
 			}
 		}

+ 9 - 1
core/wma/src/wma_utils.c

@@ -2026,6 +2026,13 @@ static int wma_copy_chan_stats(uint32_t num_chan,
 		rs_results->channels = channels;
 		return 0;
 	}
+	if (rs_results->num_channels + num_chan > NUM_CHANNELS) {
+		wma_err("total chan stats num unexpected %d new %d",
+			rs_results->num_channels, num_chan);
+		/* do not add more */
+		qdf_mem_free(channels);
+		return 0;
+	}
 
 	rs_results->num_channels += num_chan;
 	rs_results->channels = qdf_mem_malloc(rs_results->num_channels *
@@ -2238,7 +2245,8 @@ static int wma_unified_link_radio_stats_event_handler(void *handle,
 		chn_results =
 			(struct wifi_channel_stats *)&channels_in_this_event[0];
 		next_chan_offset = WMI_TLV_HDR_SIZE;
-		wma_debug("Channel Stats Info");
+		wma_debug("Channel Stats Info, radio id %d",
+			  radio_stats->radio_id);
 		for (count = 0; count < radio_stats->num_channels; count++) {
 			wma_nofl_debug("freq %u width %u freq0 %u freq1 %u awake time %u cca busy time %u",
 				       channel_stats->center_freq,