diff mbox series

[1/2] WPA: Ignore RSNX element in WPA connection

Message ID 20210121154037.32654-2-andrei.otcheretianski@intel.com
State Accepted
Headers show
Series [1/2] WPA: Ignore RSNX element in WPA connection | expand

Commit Message

Otcheretianski, Andrei Jan. 21, 2021, 3:40 p.m. UTC
When an AP publishes both RSN, RSNX and WPA IE, it incorrectly removes
the RSN IE in the EAPOL 3/4 message if the STA associates with WPA,
leaving only RSNXE instead of WPA IE. WPA STA fails to connect to such
AP as the WPA IE is missing.
Since RSNX is not really needed in non RSN connection, just remove it.
In addition, make sure that the non RSN STA doesn't store and validate
RSNX element which would be "missing" now in EAPOL 3/4 message.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
 src/ap/wpa_auth.c  | 4 ++++
 src/rsn_supp/wpa.c | 6 ++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

Comments

Jouni Malinen Feb. 6, 2021, 10:14 a.m. UTC | #1
On Thu, Jan 21, 2021 at 05:40:33PM +0200, Andrei Otcheretianski wrote:
> When an AP publishes both RSN, RSNX and WPA IE, it incorrectly removes
> the RSN IE in the EAPOL 3/4 message if the STA associates with WPA,
> leaving only RSNXE instead of WPA IE. WPA STA fails to connect to such
> AP as the WPA IE is missing.
> Since RSNX is not really needed in non RSN connection, just remove it.

Thanks, applied both patches, but for this part:

> In addition, make sure that the non RSN STA doesn't store and validate
> RSNX element which would be "missing" now in EAPOL 3/4 message.

I did not like the idea of not storing RSNXE in some cases and instead,
addressed this corner case in the actual validation step. This is not
really something that is supposed to ever happen in real production use
cases (i.e., SAE would be used instead of there is support for RSNXE),
but anyway, I guess this is convenient to have available for testing
purposes.
diff mbox series

Patch

diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 82a97468d6..6e0d7097c9 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -3353,6 +3353,8 @@  SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 	    wpa_ie_len > wpa_ie[1] + 2U && wpa_ie[0] == WLAN_EID_RSN) {
 		/* WPA-only STA, remove RSN IE and possible MDIE */
 		wpa_ie = wpa_ie + wpa_ie[1] + 2;
+		if (wpa_ie[0] == WLAN_EID_RSNX)
+			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN)
 			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		wpa_ie_len = wpa_ie[1] + 2;
@@ -5355,6 +5357,8 @@  int wpa_auth_resend_m3(struct wpa_state_machine *sm,
 	    wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) {
 		/* WPA-only STA, remove RSN IE and possible MDIE */
 		wpa_ie = wpa_ie + wpa_ie[1] + 2;
+		if (wpa_ie[0] == WLAN_EID_RSNX)
+			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN)
 			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		wpa_ie_len = wpa_ie[1] + 2;
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index e07527ba57..cb7de585f4 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -3701,13 +3701,15 @@  int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
 	if (!sm)
 		return -1;
 
-	os_free(sm->ap_rsnxe);
 	if (!ie || len == 0) {
 		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: clearing AP RSNXE");
+		os_free(sm->ap_rsnxe);
 		sm->ap_rsnxe = NULL;
 		sm->ap_rsnxe_len = 0;
-	} else {
+	} else if (sm->proto == WPA_PROTO_RSN) {
+		/* Store RSNXE for RSN connections only */
 		wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len);
+		os_free(sm->ap_rsnxe);
 		sm->ap_rsnxe = os_memdup(ie, len);
 		if (!sm->ap_rsnxe)
 			return -1;