From 4a0e01156054c36b6eb92f07a812e60eafe8b1e9 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 26 Apr 2018 14:27:05 +0200 Subject: [PATCH] AP: Fix HT 20/40 co-ex transition timer cancellation on iface removal When removing an interface, hostapd_bss_deinit() frees all associated STAs. If any of the stations is 40MHz intolerant, the cleanup invokes ht40_intolerant_remove(), that in turn registers a 20->40MHz transition timer for the last station (ap_ht2040_timeout() function). That timer is never canceled; once it executes, the interface is gone, most likely resulting in a segfault when referencing it. While hostapd_interface_deinit() cancels the transition timer, it does so before cleaning up STAs. Move the cancellation after STA cleanup to cancel any timer that was registered during that operation. Signed-off-by: Martin Willi --- src/ap/hostapd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 42e82cdec..f0955863e 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -2235,12 +2235,6 @@ void hostapd_interface_deinit(struct hostapd_iface *iface) hostapd_set_state(iface, HAPD_IFACE_DISABLED); -#ifdef CONFIG_IEEE80211N -#ifdef NEED_AP_MLME - hostapd_stop_setup_timers(iface); - eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL); -#endif /* NEED_AP_MLME */ -#endif /* CONFIG_IEEE80211N */ eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); iface->wait_channel_update = 0; @@ -2256,6 +2250,13 @@ void hostapd_interface_deinit(struct hostapd_iface *iface) break; hostapd_bss_deinit(iface->bss[j]); } + +#ifdef CONFIG_IEEE80211N +#ifdef NEED_AP_MLME + hostapd_stop_setup_timers(iface); + eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL); +#endif /* NEED_AP_MLME */ +#endif /* CONFIG_IEEE80211N */ }