qcacld-3.0: Validate number of links in roam sync indication

Host driver expects maximum of WLAN_UMAC_MLO_MAX_VDEVS links
info in roam sync indication. But firmware may send more
number of links than expected and it may lead to buffer overflow.
Add a check to validate the number of links.

Change-Id: Id89d23470622ba3ca7e01a99cc7c12021ca3dafd
CRs-Fixed: 3314460
这个提交包含在:
Vijay Patil
2022-09-07 13:59:43 +05:30
提交者 Madan Koyyalamudi
父节点 97254b609c
当前提交 30cb851dfb

查看文件

@@ -2207,48 +2207,65 @@ wmi_fill_data_synch_event(struct roam_offload_synch_ind *roam_sync_ind,
}
#ifdef WLAN_FEATURE_11BE_MLO
static void
static QDF_STATUS
wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
struct roam_offload_synch_ind *roam_sync_ind)
{
uint8_t i;
wmi_roam_ml_setup_links_param *setup_links;
wmi_roam_ml_key_material_param *ml_key_param;
struct ml_setup_link_param *link;
struct ml_key_material_param *key;
if (param_buf->num_setup_links_param) {
roam_sync_ind->num_setup_links = param_buf->num_setup_links_param;
if (param_buf->num_setup_links_param >
WLAN_UMAC_MLO_MAX_VDEVS) {
wmi_err("Number of umac mlo vdev entries %d exceeded max vdev supported %d",
param_buf->num_setup_links_param,
WLAN_UMAC_MLO_MAX_VDEVS);
return QDF_STATUS_E_INVAL;
}
roam_sync_ind->num_setup_links =
param_buf->num_setup_links_param;
setup_links = param_buf->setup_links_param;
for (i = 0; i < roam_sync_ind->num_setup_links; i++) {
roam_sync_ind->ml_link[i].link_id = setup_links->link_id;
roam_sync_ind->ml_link[i].vdev_id = setup_links->vdev_id;
roam_sync_ind->ml_link[i].channel = setup_links->channel;
roam_sync_ind->ml_link[i].flags = setup_links->flags;
link = &roam_sync_ind->ml_link[i];
link->link_id = setup_links->link_id;
link->vdev_id = setup_links->vdev_id;
link->channel = setup_links->channel;
link->flags = setup_links->flags;
WMI_MAC_ADDR_TO_CHAR_ARRAY(&setup_links->link_addr,
roam_sync_ind->ml_link[i].link_addr.bytes);
link->link_addr.bytes);
setup_links++;
}
}
if (param_buf->num_ml_key_material) {
roam_sync_ind->num_ml_key_material = param_buf->num_ml_key_material;
roam_sync_ind->num_ml_key_material =
param_buf->num_ml_key_material;
ml_key_param = param_buf->ml_key_material;
for (i = 0; i < roam_sync_ind->num_ml_key_material; i++) {
roam_sync_ind->ml_key[i].link_id = ml_key_param->link_id;
roam_sync_ind->ml_key[i].key_idx = ml_key_param->key_ix;
roam_sync_ind->ml_key[i].key_cipher = ml_key_param->key_cipher;
qdf_mem_copy(roam_sync_ind->ml_key[i].pn,
ml_key_param->pn, WMI_MAX_PN_LEN);
qdf_mem_copy(roam_sync_ind->ml_key[i].key_buff,
ml_key_param->key_buff, WMI_MAX_KEY_LEN);
key = &roam_sync_ind->ml_key[i];
key->link_id = ml_key_param->link_id;
key->key_idx = ml_key_param->key_ix;
key->key_cipher = ml_key_param->key_cipher;
qdf_mem_copy(key->pn, ml_key_param->pn,
WMI_MAX_PN_LEN);
qdf_mem_copy(key->key_buff, ml_key_param->key_buff,
WMI_MAX_KEY_LEN);
ml_key_param++;
}
}
return QDF_STATUS_SUCCESS;
}
#else
static void wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
struct roam_offload_synch_ind *roam_sync_ind)
static QDF_STATUS
wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
struct roam_offload_synch_ind *roam_sync_ind)
{
return QDF_STATUS_SUCCESS;
}
#endif
@@ -2422,7 +2439,11 @@ wmi_fill_roam_sync_buffer(struct wlan_objmgr_vdev *vdev,
pmk_cache_info->pmkid, PMKID_LEN);
}
wmi_fill_roam_mlo_info(param_buf, roam_sync_ind);
status = wmi_fill_roam_mlo_info(param_buf, roam_sync_ind);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_err("Failed to fill roam mlo info");
return status;
}
wlan_cm_free_roam_synch_frame_ind(rso_cfg);
return QDF_STATUS_SUCCESS;
}