Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 074d2855 authored by Vinod Kumar Myadam's avatar Vinod Kumar Myadam Committed by Gerrit - the friendly Code Review server
Browse files

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
parent 1ff1a00b
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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 = &param_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++;