Răsfoiți Sursa

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 2 ani în urmă
părinte
comite
30cb851dfb
1 a modificat fișierele cu 39 adăugiri și 18 ștergeri
  1. 39 18
      components/wmi/src/wmi_unified_roam_tlv.c

+ 39 - 18
components/wmi/src/wmi_unified_roam_tlv.c

@@ -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;
 }