From: Jouni Malinen Date: Sun, 14 Mar 2021 22:45:20 +0000 (+0200) Subject: EAP peer: Make EAP-Success handling more robust against race conditions X-Git-Tag: hostap_2_10~396 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c733664be9dd3763c03f2da2cb32a23775dde388;p=thirdparty%2Fhostap.git EAP peer: Make EAP-Success handling more robust against race conditions When ERP initialization was moved from the METHOD state to the SUCCESS state, the conditions for checking against EAP state being cleared was missed. The METHOD state verified that sm->m is not NULL while the SUCCESS state did not have such a check. This opened a window for a race condition where processing of deauthentication event and EAPOL RX events could end up delivering an EAP-Success to the EAP peer state machine after the state had been cleared. This issue has now been worked around in another manner, but the root cause for this regression should be fixed as well. Check that the EAP state machine is properly configured before trying to initialize ERP in the SUCCESS state. Fixes: 2a71673e27e9 ("ERP: Derive ERP key only after successful EAP authentication") Signed-off-by: Jouni Malinen --- diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 74c2ad361..7dcfe4fff 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -1069,6 +1069,20 @@ SM_STATE(EAP, SUCCESS) wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS "EAP authentication completed successfully"); + if (!config || !sm->m) { + /* + * This should not happen under normal conditions, but be more + * careful here since there was an earlier case where + * EAP-Success could end up getting delivered to the state + * machine for processing after the state had been cleaned with + * a call to eap_invalidate_cached_session() (and also + * eapol_sm_notify_config() having been used to clear EAP + * configuration in the EAPOL state machine). + */ + wpa_printf(MSG_DEBUG, + "EAP: State machine not configured - cannot initialize ERP"); + return; + } if (config->erp && sm->m->get_emsk && sm->eapSessionId && sm->m->isKeyAvailable && sm->m->isKeyAvailable(sm, sm->eap_method_priv))