Kaynağa Gözat

qcacld-3.0: Fix potential OOB read in wma_populate_soc_caps

In function wma_populate_soc_caps, param_buf is received from the FW and
soc_hw_mode_caps->num_hw_modes denotes the number of HW mode capabilities
included under hw_mode_caps. However, the actual length of the
hw_mode_caps buffer filled by the FW is num_hw_mode_caps.
If the value of soc_hw_mode_caps->num_hw_modes is greater than
num_hw_mode_caps, then an OOB read would occur while copying the FW buffer
for hw_mode_caps.

Similarly, soc_hal_reg_caps->num_phy denotes the number of hal_reg_caps
included in the FW buffer. However the actual length of the hal_reg_caps
is num_hal_reg_caps. If the value of soc_hal_reg_caps->num_phy is greater
than num_hal_reg_caps, an OOB read would occur.

Add checks to make sure soc_hw_mode_caps->num_hw_modes is not greater
than num_hw_mode_caps.
Also add check to make sure soc_hal_reg_caps->num_phy is not greater
than num_hal_reg_caps.

Change-Id: I3accffca3fc83f7e614d8f9a5bb850733a508ff7
CRs-Fixed: 2160423
Vignesh Viswanathan 7 yıl önce
ebeveyn
işleme
c279230cfc
1 değiştirilmiş dosya ile 7 ekleme ve 4 silme
  1. 7 4
      core/wma/src/wma_main.c

+ 7 - 4
core/wma/src/wma_main.c

@@ -5943,8 +5943,9 @@ static void wma_populate_soc_caps(t_wma_handle *wma_handle,
 		return;
 	}
 
-	if (param_buf->soc_hw_mode_caps->num_hw_modes >
-			MAX_NUM_HW_MODE) {
+	if ((param_buf->soc_hw_mode_caps->num_hw_modes > MAX_NUM_HW_MODE) ||
+	    (param_buf->soc_hw_mode_caps->num_hw_modes >
+	    param_buf->num_hw_mode_caps)) {
 		WMA_LOGE("Invalid num_hw_modes %u received from firmware",
 			 param_buf->soc_hw_mode_caps->num_hw_modes);
 		return;
@@ -6025,10 +6026,12 @@ static void wma_populate_soc_caps(t_wma_handle *wma_handle,
 	 * next thing is to populate reg caps per phy
 	 */
 
-	if (param_buf->soc_hal_reg_caps->num_phy >
-			MAX_NUM_PHY) {
+	if ((param_buf->soc_hal_reg_caps->num_phy > MAX_NUM_PHY) ||
+	    (param_buf->soc_hal_reg_caps->num_phy >
+	    param_buf->num_hal_reg_caps)) {
 		WMA_LOGE("Invalid num_phy %u received from firmware",
 			 param_buf->soc_hal_reg_caps->num_phy);
+		wma_cleanup_dbs_phy_caps(wma_handle);
 		return;
 	}