Message ID | 20180426122705.6057-1-martin@strongswan.org |
---|---|
State | Accepted |
Headers | show |
Series | AP: Fix HT 20/40 co-ex transition timer cancellation on iface removal | expand |
On Thu, Apr 26, 2018 at 02:27:05PM +0200, Martin Willi wrote: > 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. 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. Thanks, applied. > I'm not sure if this is the correct/best place for this cancellation, given > that hostapd_bss_deinit() is called from other locations. This code path > is rather easy to hit when using the ctrl interface, though. This looks like a reasonable change on its own. If something else is needed, that can be handled separately.
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index d2eb0441c..05956461c 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -2191,12 +2191,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; @@ -2212,6 +2206,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 */ }
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. 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 <martin@strongswan.org> --- I'm not sure if this is the correct/best place for this cancellation, given that hostapd_bss_deinit() is called from other locations. This code path is rather easy to hit when using the ctrl interface, though. --- src/ap/hostapd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)