From 2c0924538562b08d815f911a16fbd339a023ddaa Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Wed, 10 Oct 2018 17:03:28 +0800 Subject: [PATCH] qcacmn: Avoid OOB in create_reg_rules_from_wmi the fixed_param TLV structure is pulled from the WMI message and assigned to chan_list_event_hdr. num_2g_reg_rules and num_5g_reg_rules are assigned from the TLV structure, then passed to create_reg_rules_from_wmi without length check, out of buffer may happen. Change-Id: I70c9d74ef94161896e1c7700c73943040f3a77e1 CRs-Fixed: 2327667 --- wmi/src/wmi_unified_tlv.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index ba8fdc394cfa..b0c55191923f 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -9624,6 +9624,25 @@ static QDF_STATUS extract_reg_chan_list_update_event_tlv( reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; + num_2g_reg_rules = reg_info->num_2g_reg_rules; + num_5g_reg_rules = reg_info->num_5g_reg_rules; + if ((num_2g_reg_rules > MAX_REG_RULES) || + (num_5g_reg_rules > MAX_REG_RULES) || + (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || + (num_2g_reg_rules + num_5g_reg_rules != + param_buf->num_reg_rule_array)) { + wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", + num_2g_reg_rules, num_5g_reg_rules); + return QDF_STATUS_E_FAILURE; + } + if (param_buf->num_reg_rule_array > + (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / + sizeof(*wmi_reg_rule)) { + wmi_err_rl("Invalid num_reg_rule_array: %u", + param_buf->num_reg_rule_array); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), REG_ALPHA2_LEN); reg_info->dfs_region = chan_list_event_hdr->dfs_region; @@ -9656,9 +9675,6 @@ static QDF_STATUS extract_reg_chan_list_update_event_tlv( reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; - num_2g_reg_rules = reg_info->num_2g_reg_rules; - num_5g_reg_rules = reg_info->num_5g_reg_rules; - WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", __func__, reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, reg_info->max_bw_2g,