qcacld-2.0: Fix multiple length definition issue in WLAN FW message
Currently, firmware fills the num variables value of param_tlvs structure for all wmi commands. But during buffer write the fixed param values are used to check maximum limit of buffer in wmi commands. Due to multiple length definition of num variable in WLAN FW message, num variables of param_tlvs may not equal to max limit defined in fixed_param, resulting OOB issues in WLAN FW messages during buffer write. Add sanity check to make sure that num variables value doesn’t exceed max limit of num value defined in param_tlvs. Change-Id: I43c15557057ab5b900f19b9f54426dcdf85e2c27 CRs-Fixed: 2226556
This commit is contained in:
parent
1dae7178e7
commit
68b103fb46
|
@ -596,6 +596,12 @@ static int tlshim_mgmt_rx_process(void *context, u_int8_t *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (hdr->buf_len > param_tlvs->num_bufp) {
|
||||
TLSHIM_LOGE("Invalid length of frame hdr->buf_len:%u, param_tlvs->num_bufp:%u",
|
||||
hdr->buf_len, param_tlvs->num_bufp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdr->buf_len < sizeof(struct ieee80211_frame) ||
|
||||
(!saved_beacon && hdr->buf_len > data_len)) {
|
||||
adf_os_spin_unlock_bh(&tl_shim->mgmt_lock);
|
||||
|
|
|
@ -2949,10 +2949,12 @@ static int wma_link_status_event_handler(void *handle, u_int8_t *cmd_param_info,
|
|||
|
||||
event = param_buf->fixed_param;
|
||||
if (event->num_vdev_stats > ((WMA_SVC_MSG_MAX_SIZE -
|
||||
sizeof(*event)) / sizeof(wmi_vdev_rate_ht_info))) {
|
||||
WMA_LOGE("%s: excess vdev_stats buffers:%d", __func__,
|
||||
event->num_vdev_stats);
|
||||
VOS_ASSERT(0);
|
||||
sizeof(*event)) / sizeof(wmi_vdev_rate_ht_info)) ||
|
||||
event->num_vdev_stats > param_buf->num_ht_info) {
|
||||
WMA_LOGE("%s: excess vdev_stats buffers:%d, num_ht_info:%d",
|
||||
__func__,
|
||||
event->num_vdev_stats,
|
||||
param_buf->num_ht_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
buf_size = sizeof(wmi_vdev_rate_stats_event_fixed_param) +
|
||||
|
@ -3770,6 +3772,10 @@ static int wma_extscan_hotlist_match_event_handler(void *handle,
|
|||
WMA_LOGE("%s: Hotlist AP's list invalid", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (numap > param_buf->num_hotlist_match) {
|
||||
WMA_LOGE("Invalid no of total enteries %d", numap);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (numap > WMA_EXTSCAN_MAX_HOTLIST_ENTRIES) {
|
||||
WMA_LOGE("%s: Total Entries %u greater than max",
|
||||
__func__, numap);
|
||||
|
@ -4068,9 +4074,11 @@ static int wma_extscan_cached_results_event_handler(void *handle,
|
|||
goto noresults;
|
||||
}
|
||||
if (event->num_entries_in_page >
|
||||
(WMA_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist)) {
|
||||
WMA_LOGE("%s:excess num_entries_in_page %d in WMI event",
|
||||
__func__, event->num_entries_in_page);
|
||||
(WMA_SVC_MSG_MAX_SIZE - sizeof(*event))/sizeof(*src_hotlist) ||
|
||||
event->num_entries_in_page > param_buf->num_bssid_list) {
|
||||
WMA_LOGE("%s:excess num_entries_in_page %d in WMI event. num_bssid_list %d",
|
||||
__func__,
|
||||
event->num_entries_in_page, param_buf->num_bssid_list);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
total_len = sizeof(*event) +
|
||||
|
@ -4201,6 +4209,10 @@ static int wma_extscan_change_results_event_handler(void *handle,
|
|||
WMA_LOGE("%s: Results invalid", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (numap > param_buf->num_bssid_signal_descriptor_list) {
|
||||
WMA_LOGE("%s: Invalid num of entries in page: %d", __func__, numap);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < numap; i++) {
|
||||
if (src_chglist->num_rssi_samples > (UINT_MAX - rssi_num)) {
|
||||
WMA_LOGE("%s: Invalid num of rssi samples %d numap %d rssi_num %d",
|
||||
|
@ -4258,6 +4270,13 @@ static int wma_extscan_change_results_event_handler(void *handle,
|
|||
dest_ap->numOfRssi =
|
||||
src_chglist->num_rssi_samples;
|
||||
if (dest_ap->numOfRssi) {
|
||||
if ((dest_ap->numOfRssi + count) >
|
||||
param_buf->num_rssi_list) {
|
||||
WMA_LOGE("%s: Invalid num in rssi list: %d",
|
||||
__func__, dest_ap->numOfRssi);
|
||||
vos_mem_free(dest_chglist);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (k = 0; k < dest_ap->numOfRssi; k++) {
|
||||
dest_ap->rssi[k] = WMA_TGT_NOISE_FLOOR_DBM +
|
||||
src_rssi[count++];
|
||||
|
@ -4441,9 +4460,10 @@ static int wma_unified_link_iface_stats_event_handler(void *handle,
|
|||
WMA_LOGA("%s: Invalid param_tlvs for Iface Stats", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (link_stats->num_ac > WIFI_AC_MAX) {
|
||||
WMA_LOGE("%s: Excess data received from firmware num_ac %d",
|
||||
__func__, link_stats->num_ac);
|
||||
if (link_stats->num_ac > WIFI_AC_MAX || link_stats->num_ac >
|
||||
param_tlvs->num_ac) {
|
||||
WMA_LOGE("%s: Excess data received from firmware num_ac %d, param_tlvs->num_ac %d",
|
||||
__func__, link_stats->num_ac, param_tlvs->num_ac);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -4607,7 +4627,8 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
|
||||
do {
|
||||
if (fixed_param->num_peers >
|
||||
WMA_SVC_MSG_MAX_SIZE/sizeof(wmi_peer_link_stats)) {
|
||||
WMA_SVC_MSG_MAX_SIZE/sizeof(wmi_peer_link_stats) ||
|
||||
fixed_param->num_peers > param_tlvs->num_peer_stats) {
|
||||
excess_data = true;
|
||||
break;
|
||||
} else {
|
||||
|
@ -4624,7 +4645,8 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
total_num_rates += temp_peer_stats->num_rates;
|
||||
if (total_num_rates >
|
||||
WMA_SVC_MSG_MAX_SIZE /
|
||||
sizeof(wmi_rate_stats)) {
|
||||
sizeof(wmi_rate_stats) || total_num_rates >
|
||||
param_tlvs->num_peer_rate_stats) {
|
||||
excess_data = true;
|
||||
break;
|
||||
}
|
||||
|
@ -4639,7 +4661,6 @@ static int wma_unified_link_peer_stats_event_handler(void *handle,
|
|||
(buf_len > WMA_SVC_MSG_MAX_SIZE - sizeof(*fixed_param))) {
|
||||
WMA_LOGE("excess wmi buffer: rates:%d, peers:%d",
|
||||
peer_stats->num_rates, fixed_param->num_peers);
|
||||
VOS_ASSERT(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -4778,7 +4799,8 @@ static int wma_unified_link_radio_stats_event_handler(void *handle,
|
|||
}
|
||||
|
||||
if (radio_stats->num_channels >
|
||||
NUM_2_4GHZ_CHANNELS + NUM_5GHZ_CHANNELS) {
|
||||
(NUM_2_4GHZ_CHANNELS + NUM_5GHZ_CHANNELS) ||
|
||||
radio_stats->num_channels > param_tlvs->num_channel_stats) {
|
||||
WMA_LOGE("%s: Too many channels %d",
|
||||
__func__, radio_stats->num_channels);
|
||||
return -EINVAL;
|
||||
|
@ -6142,8 +6164,8 @@ static int wma_nan_rsp_event_handler(void *handle, u_int8_t *event_buf,
|
|||
if (nan_rsp_event_hdr->data_len > ((WMA_SVC_MSG_MAX_SIZE -
|
||||
WMI_TLV_HDR_SIZE - sizeof(*nan_rsp_event_hdr)) / sizeof(u_int8_t)) ||
|
||||
nan_rsp_event_hdr->data_len > param_buf->num_data) {
|
||||
WMA_LOGE("excess data length:%d", nan_rsp_event_hdr->data_len);
|
||||
VOS_ASSERT(0);
|
||||
WMA_LOGE("excess data length:%d, num_data:%d",
|
||||
nan_rsp_event_hdr->data_len, param_buf->num_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
nan_rsp_event = (tSirNanEvent *) vos_mem_malloc(alloc_len);
|
||||
|
@ -6491,6 +6513,19 @@ static int wma_roam_synch_event_handler(void *handle, u_int8_t *event, u_int32_t
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (synch_event->bcn_probe_rsp_len >
|
||||
param_buf->num_bcn_probe_rsp_frame ||
|
||||
synch_event->reassoc_req_len >
|
||||
param_buf->num_reassoc_req_frame ||
|
||||
synch_event->reassoc_rsp_len >
|
||||
param_buf->num_reassoc_rsp_frame) {
|
||||
WMA_LOGE("Invalid synch payload: LEN bcn:%d, req:%d, rsp:%d",
|
||||
synch_event->bcn_probe_rsp_len,
|
||||
synch_event->reassoc_req_len,
|
||||
synch_event->reassoc_rsp_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(wma->interfaces[synch_event->vdev_id].roam_synch_in_progress ==
|
||||
VOS_TRUE) {
|
||||
WMA_LOGE("%s: Ignoring RSI since one is already in progress",
|
||||
|
@ -6845,7 +6880,8 @@ static int wma_stats_ext_event_handler(void *handle, u_int8_t *event_buf,
|
|||
if (stats_ext_info->data_len > (WMA_SVC_MSG_MAX_SIZE -
|
||||
WMI_TLV_HDR_SIZE - sizeof(*stats_ext_info)) ||
|
||||
stats_ext_info->data_len > param_buf->num_data) {
|
||||
WMA_LOGE("Excess data_len:%d", stats_ext_info->data_len);
|
||||
WMA_LOGE("Excess data_len:%d, num_data:%d",
|
||||
stats_ext_info->data_len, param_buf->num_data);
|
||||
VOS_ASSERT(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -30452,7 +30488,11 @@ static int wma_channel_avoid_evt_handler(void *handle, u_int8_t *event,
|
|||
|
||||
num_freq_ranges = (afr_fixed_param->num_freq_ranges > SIR_CH_AVOID_MAX_RANGE)?
|
||||
SIR_CH_AVOID_MAX_RANGE:afr_fixed_param->num_freq_ranges;
|
||||
|
||||
if (num_freq_ranges > param_buf->num_avd_freq_range) {
|
||||
WMA_LOGE("Invalid num_freq_ranges %d, avd_freq_range %d",
|
||||
num_freq_ranges, param_buf->num_avd_freq_range);
|
||||
return -EINVAL;
|
||||
}
|
||||
WMA_LOGD("Channel avoid event received with %d ranges", num_freq_ranges);
|
||||
for (freq_range_idx = 0; freq_range_idx < num_freq_ranges; freq_range_idx++) {
|
||||
afr_desc = (wmi_avoid_freq_range_desc *) ((void *)param_buf->avd_freq_range
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
|
@ -807,10 +807,12 @@ int wma_dcc_get_stats_resp_event_handler(void *handle, uint8_t *event_buf,
|
|||
|
||||
/* Allocate and populate the response */
|
||||
if (fix_param->num_channels > ((WMA_SVC_MSG_MAX_SIZE -
|
||||
sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel))) {
|
||||
WMA_LOGE("%s: too many channels:%d", __func__,
|
||||
fix_param->num_channels);
|
||||
VOS_ASSERT(0);
|
||||
sizeof(*fix_param)) / sizeof(wmi_dcc_ndl_stats_per_channel)) ||
|
||||
fix_param->num_channels > param_tlvs->num_stats_per_channel_list) {
|
||||
WMA_LOGE("%s: too many channels:%d, param_tlvs->num_stats_per_channel_list:%d",
|
||||
__func__,
|
||||
fix_param->num_channels,
|
||||
param_tlvs->num_stats_per_channel_list);
|
||||
return -EINVAL;
|
||||
}
|
||||
response = vos_mem_malloc(sizeof(*response) + fix_param->num_channels *
|
||||
|
|
Loading…
Reference in New Issue