From 074d28559711535252db6397b2f915c9c2976c46 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Myadam Date: Thu, 16 Feb 2023 18:09:50 +0530 Subject: [PATCH] qcacmn: Fix out-of-bounds of src_freq When handling WMI_ROAM_SCAN_STATS_EVENTID, the number of channels scanned for each roam trigger is fetched from wmi_roam_scan_info TLV (wmi_roam_scan_info->roam_scan_channel_count), The total number of channels for all the roam triggers is fetched from param_buf->num_roam_scan_chan_info. chan_idx is the index used to fetch the current channel info TLV to be read. So if wmi_roam_scan_info->roam_scan_channel_count provided by firmware exceeds the total param_buf->num_roam_scan_chan_info starting from given chan_idx then OOB access of event buffer can happen. To avoid this, validate the sum of the current chan_idx and src_data->roam_scan_channel_count against evt_buf->num_roam_scan_chan_info. Change-Id: Ied94464d1f12690cf8832962b94595c2e00c33f8 CRs-Fixed: 3357714 --- wmi/src/wmi_unified_tlv.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 3819c3ba6454..1776a8a1d621 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -14279,6 +14279,15 @@ extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, dst->num_chan = MAX_ROAM_SCAN_CHAN; src_chan = ¶m_buf->roam_scan_chan_info[chan_idx]; + + if ((dst->num_chan + chan_idx) > + param_buf->num_roam_scan_chan_info) { + wmi_err("Invalid TLV. num_chan %d chan_idx %d num_roam_scan_chan_info %d", + dst->num_chan, chan_idx, + param_buf->num_roam_scan_chan_info); + return QDF_STATUS_SUCCESS; + } + for (i = 0; i < dst->num_chan; i++) { dst->chan_freq[i] = src_chan->channel; src_chan++; @@ -14387,6 +14396,14 @@ extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf, if (dst->num_freq > MAX_ROAM_SCAN_CHAN) dst->num_freq = MAX_ROAM_SCAN_CHAN; + if ((dst->num_freq + rpt_idx) > + param_buf->num_roam_neighbor_report_chan_info) { + wmi_err("Invalid TLV. num_freq %d rpt_idx %d num_roam_neighbor_report_chan_info %d", + dst->num_freq, rpt_idx, + param_buf->num_roam_scan_chan_info); + return QDF_STATUS_SUCCESS; + } + for (i = 0; i < dst->num_freq; i++) { dst->freq[i] = src_freq->channel; src_freq++;