rtw88: fix potential read outside array boundary
authorTzu-En Huang <tehuang@realtek.com>
Fri, 25 Oct 2019 09:33:44 +0000 (17:33 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 31 Oct 2019 08:03:50 +0000 (10:03 +0200)
The level of cckpd is from 0 to 4, and it is the index of
array pd_lvl[] and cs_lvl[]. However, the length of both arrays
are 4, which is smaller than the possible maximum input index.
Enumerate cck level to make sure the max level will not be wrong
if new level is added in future.

Fixes: 479c4ee931a6 ("rtw88: add dynamic cck pd mechanism")
Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/realtek/rtw88/phy.c
drivers/net/wireless/realtek/rtw88/phy.h
drivers/net/wireless/realtek/rtw88/rtw8822c.c

index 4a41134c420eefb4faff876cbd0459c62bdcd041..4adba44dbd7490ab63a413eac1bb4f15ad7c0d50 100644 (file)
@@ -109,7 +109,7 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
 
        for (i = 0; i <= RTW_CHANNEL_WIDTH_40; i++) {
                for (j = 0; j < RTW_RF_PATH_MAX; j++)
-                       dm_info->cck_pd_lv[i][j] = 0;
+                       dm_info->cck_pd_lv[i][j] = CCK_PD_LV0;
        }
 
        dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
@@ -461,7 +461,6 @@ static void rtw_phy_dpk_track(struct rtw_dev *rtwdev)
                chip->ops->dpk_track(rtwdev);
 }
 
-#define CCK_PD_LV_MAX          5
 #define CCK_PD_FA_LV1_MIN      1000
 #define CCK_PD_FA_LV0_MAX      500
 
@@ -471,10 +470,10 @@ static u8 rtw_phy_cck_pd_lv_unlink(struct rtw_dev *rtwdev)
        u32 cck_fa_avg = dm_info->cck_fa_avg;
 
        if (cck_fa_avg > CCK_PD_FA_LV1_MIN)
-               return 1;
+               return CCK_PD_LV1;
 
        if (cck_fa_avg < CCK_PD_FA_LV0_MAX)
-               return 0;
+               return CCK_PD_LV0;
 
        return CCK_PD_LV_MAX;
 }
@@ -494,15 +493,15 @@ static u8 rtw_phy_cck_pd_lv_link(struct rtw_dev *rtwdev)
        u32 cck_fa_avg = dm_info->cck_fa_avg;
 
        if (igi > CCK_PD_IGI_LV4_VAL && rssi > CCK_PD_RSSI_LV4_VAL)
-               return 4;
+               return CCK_PD_LV4;
        if (igi > CCK_PD_IGI_LV3_VAL && rssi > CCK_PD_RSSI_LV3_VAL)
-               return 3;
+               return CCK_PD_LV3;
        if (igi > CCK_PD_IGI_LV2_VAL || rssi > CCK_PD_RSSI_LV2_VAL)
-               return 2;
+               return CCK_PD_LV2;
        if (cck_fa_avg > CCK_PD_FA_LV1_MIN)
-               return 1;
+               return CCK_PD_LV1;
        if (cck_fa_avg < CCK_PD_FA_LV0_MAX)
-               return 0;
+               return CCK_PD_LV0;
 
        return CCK_PD_LV_MAX;
 }
index c389ef274ed864d553923f25bfe575833914452d..af916d8784cd5df536e898db156ea56afbd868ac 100644 (file)
@@ -146,6 +146,15 @@ rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path,
                        u8 rate, u8 bw, u8 ch, u8 regd,
                        struct rtw_power_params *pwr_param);
 
+enum rtw_phy_cck_pd_lv {
+       CCK_PD_LV0,
+       CCK_PD_LV1,
+       CCK_PD_LV2,
+       CCK_PD_LV3,
+       CCK_PD_LV4,
+       CCK_PD_LV_MAX,
+};
+
 #define        MASKBYTE0               0xff
 #define        MASKBYTE1               0xff00
 #define        MASKBYTE2               0xff0000
index 04ced3b2a247a50e32c3219095b56f5e3270fc62..1740298368334cefdae14f63ba6b49feb2fba9fc 100644 (file)
@@ -3295,8 +3295,8 @@ rtw8822c_phy_cck_pd_set_reg(struct rtw_dev *rtwdev,
 static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
 {
        struct rtw_dm_info *dm_info = &rtwdev->dm_info;
-       s8 pd_lvl[4] = {2, 4, 6, 8};
-       s8 cs_lvl[4] = {2, 2, 2, 4};
+       s8 pd_lvl[CCK_PD_LV_MAX] = {0, 2, 4, 6, 8};
+       s8 cs_lvl[CCK_PD_LV_MAX] = {0, 2, 2, 2, 4};
        u8 cur_lvl;
        u8 nrx, bw;