mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-23 13:09:04 -04:00
qcacld-3.0: Fix integer overflow in wma_unified_link_peer_stats_event_handler
Currently in wma_unified_link_peer_stats_event_handler, the check to validate if peer_stats->num_rates is less than WMA_SVC_MSG_MAX_SIZE is done only for the first member of the peer_stats array. This can lead to integer overflow as num_rates is calculated as sum of peer_stats->num_rates for each of the peer_stats in the array. Add code changes to loop and calculate total_num_rates for all the peer_stats and then validate total_num_rates with WMA_SVC_MSG_MAX_SIZE. Change-Id: Ic934934a990bd55fce70a0eaffa2812bc34b0ddd CRs-Fixed: 2113758
This commit is contained in:
parent
391df21964
commit
53d69c9b7f
1 changed files with 25 additions and 22 deletions
|
|
@ -1224,7 +1224,8 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
wmi_rate_stats *rate_stats;
|
||||
tSirLLStatsResults *link_stats_results;
|
||||
uint8_t *results, *t_peer_stats, *t_rate_stats;
|
||||
uint32_t count, num_rates = 0, rate_cnt;
|
||||
uint32_t count, rate_cnt;
|
||||
uint32_t total_num_rates = 0;
|
||||
uint32_t next_res_offset, next_peer_offset, next_rate_offset;
|
||||
size_t peer_info_size, peer_stats_size, rate_stats_size;
|
||||
size_t link_stats_results_size;
|
||||
|
|
@ -1252,8 +1253,8 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
* cmd_param_info contains
|
||||
* wmi_peer_stats_event_fixed_param fixed_param;
|
||||
* num_peers * size of(struct wmi_peer_link_stats)
|
||||
* num_rates * size of(struct wmi_rate_stats)
|
||||
* num_rates is the sum of the rates of all the peers.
|
||||
* total_num_rates * size of(struct wmi_rate_stats)
|
||||
* total_num_rates is the sum of the rates of all the peers.
|
||||
*/
|
||||
fixed_param = param_tlvs->fixed_param;
|
||||
peer_stats = param_tlvs->peer_stats;
|
||||
|
|
@ -1266,22 +1267,33 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
}
|
||||
|
||||
do {
|
||||
if (peer_stats->num_rates >
|
||||
WMI_SVC_MSG_MAX_SIZE/sizeof(wmi_rate_stats)) {
|
||||
excess_data = true;
|
||||
break;
|
||||
} else {
|
||||
buf_len =
|
||||
peer_stats->num_rates * sizeof(wmi_rate_stats);
|
||||
}
|
||||
if (fixed_param->num_peers >
|
||||
WMI_SVC_MSG_MAX_SIZE/sizeof(wmi_peer_link_stats)) {
|
||||
excess_data = true;
|
||||
break;
|
||||
} else {
|
||||
buf_len += fixed_param->num_peers *
|
||||
buf_len = fixed_param->num_peers *
|
||||
sizeof(wmi_peer_link_stats);
|
||||
}
|
||||
temp_peer_stats = (wmi_peer_link_stats *) peer_stats;
|
||||
for (count = 0; count < fixed_param->num_peers; count++) {
|
||||
if (temp_peer_stats->num_rates >
|
||||
WMI_SVC_MSG_MAX_SIZE / sizeof(wmi_rate_stats)) {
|
||||
excess_data = true;
|
||||
break;
|
||||
} else {
|
||||
total_num_rates += temp_peer_stats->num_rates;
|
||||
if (total_num_rates >
|
||||
WMI_SVC_MSG_MAX_SIZE /
|
||||
sizeof(wmi_rate_stats)) {
|
||||
excess_data = true;
|
||||
break;
|
||||
}
|
||||
buf_len += temp_peer_stats->num_rates *
|
||||
sizeof(wmi_rate_stats);
|
||||
}
|
||||
temp_peer_stats++;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (excess_data ||
|
||||
|
|
@ -1292,22 +1304,13 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* num_rates - sum of the rates of all the peers
|
||||
*/
|
||||
temp_peer_stats = (wmi_peer_link_stats *) peer_stats;
|
||||
for (count = 0; count < fixed_param->num_peers; count++) {
|
||||
num_rates += temp_peer_stats->num_rates;
|
||||
temp_peer_stats++;
|
||||
}
|
||||
|
||||
peer_stats_size = sizeof(tSirWifiPeerStat);
|
||||
peer_info_size = sizeof(tSirWifiPeerInfo);
|
||||
rate_stats_size = sizeof(tSirWifiRateStat);
|
||||
link_stats_results_size =
|
||||
sizeof(*link_stats_results) + peer_stats_size +
|
||||
(fixed_param->num_peers * peer_info_size) +
|
||||
(num_rates * rate_stats_size);
|
||||
(total_num_rates * rate_stats_size);
|
||||
|
||||
link_stats_results = qdf_mem_malloc(link_stats_results_size);
|
||||
if (NULL == link_stats_results) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue