Search Linux Wireless

[PATCH] wifi: mac80211: avoid buffer overflow by adding clear data of VHT Tx power envelope

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



While connecting to a 6 GHz AP, the tx_pwr_env_num of struct
ieee80211_bss_conf is increased (e.g. from 0 to 1) in function
ieee80211_prep_channel().

when AP send authentication with status which is not 0 to station, then
the connection failed here, and the tx_pwr_env_num is not reset to 0,
because it is only reset to 0 in ieee80211_set_disassoc() which will not
entered for this fail. Then connect to AP again and hit same fail again,
the tx_pwr_env_num will increased again and become to 2, then it is an
invalid number because it should be 1.

When connect-fail again and again, finally it will exceed the max length
tx_pwr_env[] in struct ieee80211_bss_conf, when driver use the value of
tx_pwr_env_num to run loop to access the tx_pwr_env[], then overflow
happened here.

There are many steps while connecting to AP for station, and any one step
failure will lead connect failure, so it is hard to do reset the value of
tx_pwr_env_num for each failure case.

And the next connection maybe change to NON-6G Hz and NON-11AX-HE AP after
connection failure with 6 GHz AP, then the check of flag is_6ghz and flag
of IEEE80211_CONN_DISABLE_HE will not matched in ieee80211_prep_channel().

Hence change to assign value of tx_pwr_env_num each time in function
ieee80211_prep_channel(), then the tx_pwr_env_num will be 1 when the next
AP is still 6 GHz AP, and it will be 0 for NON-6 GHz AP , and then it
will be always avoid buffer overflow and invalid value of tx_pwr_env_num.

Signed-off-by: Wen Gong <quic_wgong@xxxxxxxxxxx>
---
 net/mac80211/mlme.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 959695ed7649..d8ca7f18028e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4712,6 +4712,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 	int ret;
 	u32 i;
 	bool have_80mhz;
+	u8 j = 0;
 
 	rcu_read_lock();
 
@@ -4789,10 +4790,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 		he_oper = elems->he_operation;
 
 		if (link && is_6ghz) {
-			struct ieee80211_bss_conf *bss_conf;
-			u8 j = 0;
-
-			bss_conf = link->conf;
+			struct ieee80211_bss_conf *bss_conf = link->conf;;
 
 			if (elems->pwr_constr_elem)
 				bss_conf->pwr_reduction = *elems->pwr_constr_elem;
@@ -4805,7 +4803,6 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 				    sizeof(bss_conf->tx_pwr_env[j]))
 					continue;
 
-				bss_conf->tx_pwr_env_num++;
 				memcpy(&bss_conf->tx_pwr_env[j], elems->tx_pwr_env[i],
 				       elems->tx_pwr_env_len[i]);
 				j++;
@@ -4818,6 +4815,8 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 				       IEEE80211_CONN_DISABLE_EHT;
 	}
 
+	link->conf->tx_pwr_env_num = j;
+
 	/*
 	 * EHT requires HE to be supported as well. Specifically for 6 GHz
 	 * channels, the operation channel information can only be deduced from

base-commit: b21fe5be53eb873c02e7479372726c8aeed171e3
-- 
2.40.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux