qcacmn: Avoid buffer overflow in roam scan stats extract handler
In extract_roam_scan_stats_res_evt_tlv(), there is potential buffer-overflow due to no input validation of following event parameters from firmware: (a) Roam scan frequencies against maximum value of 50 (WMI_ROAM_SCAN_STATS_CHANNELS_MAX) and (b) Roam scan candidates against maximum value of 4 (WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) To fix this, validate roam scan stats event parameters. Change-Id: I866b492f7ccb48c4960ff25a9e817cbdb394509e CRs-Fixed: 2335530
This commit is contained in:

gecommit door
nshrivas

bovenliggende
78b6ac9cec
commit
d7b4847bee
@@ -10377,13 +10377,14 @@ extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
|
||||
num_scans = fixed_param->num_roam_scans;
|
||||
scan_param_size = sizeof(struct wmi_roam_scan_stats_params);
|
||||
if ((num_scans > ((UINT_MAX - sizeof(*res)) / scan_param_size))) {
|
||||
wmi_err_rl("Invalid num_roam_scans %d", num_scans);
|
||||
*vdev_id = fixed_param->vdev_id;
|
||||
if (num_scans > WMI_ROAM_SCAN_STATS_MAX) {
|
||||
wmi_err_rl("%u exceeded maximum roam scan stats: %u",
|
||||
num_scans, WMI_ROAM_SCAN_STATS_MAX);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
total_len = sizeof(*res) + num_scans * scan_param_size;
|
||||
*vdev_id = fixed_param->vdev_id;
|
||||
|
||||
res = qdf_mem_malloc(total_len);
|
||||
if (!res) {
|
||||
@@ -10425,8 +10426,16 @@ extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
uint32_t count, chan_info_sum = 0;
|
||||
|
||||
num_channels = param_buf->num_channels;
|
||||
for (count = 0; count < param_buf->num_num_channels; count++)
|
||||
for (count = 0; count < param_buf->num_num_channels; count++) {
|
||||
if (param_buf->num_channels[count] >
|
||||
WMI_ROAM_SCAN_STATS_CHANNELS_MAX) {
|
||||
wmi_err_rl("%u exceeded max scan channels %u",
|
||||
param_buf->num_channels[count],
|
||||
WMI_ROAM_SCAN_STATS_CHANNELS_MAX);
|
||||
goto error;
|
||||
}
|
||||
chan_info_sum += param_buf->num_channels[count];
|
||||
}
|
||||
|
||||
if (param_buf->chan_info &&
|
||||
param_buf->num_chan_info == chan_info_sum)
|
||||
@@ -10435,12 +10444,19 @@ extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
|
||||
if (param_buf->num_roam_candidates &&
|
||||
param_buf->num_num_roam_candidates == num_scans) {
|
||||
uint32_t count, roam_cand_sum = 0;
|
||||
uint32_t cnt, roam_cand_sum = 0;
|
||||
|
||||
num_roam_candidates = param_buf->num_roam_candidates;
|
||||
for (count = 0; count < param_buf->num_num_roam_candidates;
|
||||
count++)
|
||||
roam_cand_sum += param_buf->num_roam_candidates[count];
|
||||
for (cnt = 0; cnt < param_buf->num_num_roam_candidates; cnt++) {
|
||||
if (param_buf->num_roam_candidates[cnt] >
|
||||
WMI_ROAM_SCAN_STATS_CANDIDATES_MAX) {
|
||||
wmi_err_rl("%u exceeded max scan cand %u",
|
||||
param_buf->num_roam_candidates[cnt],
|
||||
WMI_ROAM_SCAN_STATS_CANDIDATES_MAX);
|
||||
goto error;
|
||||
}
|
||||
roam_cand_sum += param_buf->num_roam_candidates[cnt];
|
||||
}
|
||||
|
||||
if (param_buf->bssid &&
|
||||
param_buf->num_bssid == roam_cand_sum)
|
||||
@@ -10520,6 +10536,9 @@ extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
*res_param = res;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
error:
|
||||
qdf_mem_free(res);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Verwijs in nieuw issue
Block a user