lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221104163339.227432-1-marex@denx.de>
Date:   Fri,  4 Nov 2022 17:33:39 +0100
From:   Marek Vasut <marex@...x.de>
To:     linux-wireless@...r.kernel.org
Cc:     Marek Vasut <marex@...x.de>,
        Amitkumar Karwar <amit.karwar@...pinesignals.com>,
        Angus Ainslie <angus@...ea.ca>,
        Jakub Kicinski <kuba@...nel.org>,
        Johannes Berg <johannes@...solutions.net>,
        Kalle Valo <kvalo@...nel.org>,
        Martin Fuzzey <martin.fuzzey@...wbird.group>,
        Martin Kepplinger <martink@...teo.de>,
        Prameela Rani Garnepudi <prameela.j04cs@...il.com>,
        Sebastian Krzyszkowiak <sebastian.krzyszkowiak@...i.sm>,
        Siva Rebbagondla <siva8118@...il.com>, netdev@...r.kernel.org
Subject: [PATCH v5] wifi: rsi: Fix handling of 802.3 EAPOL frames sent via control port

When using wpa_supplicant v2.10, this driver is no longer able to
associate with any AP and fails in the EAPOL 4-way handshake while
sending the 2/4 message to the AP. The problem is not present in
wpa_supplicant v2.9 or older. The problem stems from HostAP commit
144314eaa ("wpa_supplicant: Send EAPOL frames over nl80211 where available")
which changes the way EAPOL frames are sent, from them being send
at L2 frames to them being sent via nl80211 control port.

An EAPOL frame sent as L2 frame is passed to the WiFi driver with
skb->protocol ETH_P_PAE, while EAPOL frame sent via nl80211 control
port has skb->protocol set to ETH_P_802_3 . The later happens in
ieee80211_tx_control_port(), where the EAPOL frame is encapsulated
into 802.3 frame.

The rsi_91x driver handles ETH_P_PAE EAPOL frames as high-priority
frames and sends them via highest-priority transmit queue, while
the ETH_P_802_3 frames are sent as regular frames. The EAPOL 4-way
handshake frames must be sent as highest-priority, otherwise the
4-way handshake times out.

Therefore, to fix this problem, inspect the skb control flags and
if flag IEEE80211_TX_CTRL_PORT_CTRL_PROTO is set, assume this is
an EAPOL frame and transmit the frame via high-priority queue just
like other ETH_P_PAE frames.

Fixes: 0eb42586cf87 ("rsi: data packet descriptor enhancements")
Signed-off-by: Marek Vasut <marex@...x.de>
---
NOTE: I am really unsure about the method of finding out the exact
      place of ethernet header in the encapsulated packet and then
      extracting the ethertype from it. Is there maybe some sort of
      helper function for that purpose ?
---
V2: - Turn the duplicated code into common function
V3: - Simplify the TX EAPOL detection (Johannes)
V4: - Drop the double !!() from test
    - Update commit message
V5: - Inline the rsi_is_tx_eapol() again, undoes V2 change completely
---
Cc: Amitkumar Karwar <amit.karwar@...pinesignals.com>
Cc: Angus Ainslie <angus@...ea.ca>
Cc: Jakub Kicinski <kuba@...nel.org>
Cc: Johannes Berg <johannes@...solutions.net>
Cc: Kalle Valo <kvalo@...nel.org>
Cc: Martin Fuzzey <martin.fuzzey@...wbird.group>
Cc: Martin Kepplinger <martink@...teo.de>
Cc: Prameela Rani Garnepudi <prameela.j04cs@...il.com>
Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@...i.sm>
Cc: Siva Rebbagondla <siva8118@...il.com>
Cc: linux-wireless@...r.kernel.org
Cc: netdev@...r.kernel.org
---
 drivers/net/wireless/rsi/rsi_91x_core.c | 4 +++-
 drivers/net/wireless/rsi/rsi_91x_hal.c  | 6 +++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index 0f3a80f66b61c..ead4d4e043280 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -466,7 +466,9 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
 							      tid, 0);
 			}
 		}
-		if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
+
+		if (IEEE80211_SKB_CB(skb)->control.flags &
+		    IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
 			q_num = MGMT_SOFT_Q;
 			skb->priority = q_num;
 		}
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index c61f83a7333b6..c7460fbba0142 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -162,12 +162,16 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 	u8 header_size;
 	u8 vap_id = 0;
 	u8 dword_align_bytes;
+	bool tx_eapol;
 	u16 seq_num;
 
 	info = IEEE80211_SKB_CB(skb);
 	vif = info->control.vif;
 	tx_params = (struct skb_info *)info->driver_data;
 
+	tx_eapol = IEEE80211_SKB_CB(skb)->control.flags &
+		   IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
+
 	header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
 	if (header_size > skb_headroom(skb)) {
 		rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
@@ -231,7 +235,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
 		}
 	}
 
-	if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
+	if (tx_eapol) {
 		rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
 
 		data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
-- 
2.35.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ