More robust timer_tick_enabled tracking

Do not set sm->timer_tick_enabled if the eloop_register_timeout() call
fails so that the next attempt to enable the timer in
eapol_enable_timer_tick() can try to recover from unexpected eloop
failures. This should not really be needed in practical use cases, but
certain out-of-memory test cases can trigger allocation failure in
eloop_register_timeout() and if that happens, the previous EAPOL
supplicant state machine implementation got pretty much completely stuck
for any operation needing the timer.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2019-03-13 23:25:21 +02:00 committed by Jouni Malinen
parent 64766a7783
commit 673631b8a3

View file

@ -189,8 +189,9 @@ static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
}
if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) {
eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx,
sm);
if (eloop_register_timeout(1, 0, eapol_port_timers_tick,
eloop_ctx, sm) < 0)
sm->timer_tick_enabled = 0;
} else {
wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick");
sm->timer_tick_enabled = 0;
@ -204,9 +205,9 @@ static void eapol_enable_timer_tick(struct eapol_sm *sm)
if (sm->timer_tick_enabled)
return;
wpa_printf(MSG_DEBUG, "EAPOL: enable timer tick");
sm->timer_tick_enabled = 1;
eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
if (eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm) == 0)
sm->timer_tick_enabled = 1;
}
@ -2141,8 +2142,8 @@ struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
sm->initialize = FALSE;
eapol_sm_step(sm);
sm->timer_tick_enabled = 1;
eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
if (eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm) == 0)
sm->timer_tick_enabled = 1;
return sm;
}