Commit 18a0696e authored by Tzu-En Huang's avatar Tzu-En Huang Committed by Kalle Valo
Browse files

rtw88: fix potential read outside array boundary



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: 479c4ee9 ("rtw88: add dynamic cck pd mechanism")
Signed-off-by: default avatarTzu-En Huang <tehuang@realtek.com>
Signed-off-by: default avatarYan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent ff0dfe5b
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -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;
}
+9 −0
Original line number Diff line number Diff line
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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;