Message ID | 20230113212436.794519-1-prestwoj@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2,1/3] station: add checks to prevent multiple roam scans | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
prestwoj/iwd-alpine-ci-fetch | success | Fetch PR |
prestwoj/iwd-ci-gitlint | success | GitLint |
prestwoj/iwd-ci-fetch | success | Fetch PR |
prestwoj/iwd-ci-makedistcheck | success | Make Distcheck |
prestwoj/iwd-alpine-ci-makedistcheck | success | Make Distcheck |
prestwoj/iwd-ci-build | success | Build - Configure |
prestwoj/iwd-alpine-ci-build | success | Build - Configure |
prestwoj/iwd-ci-clang | success | clang PASS |
prestwoj/iwd-ci-makecheckvalgrind | success | Make Check w/Valgrind |
prestwoj/iwd-ci-makecheck | success | Make Check |
prestwoj/iwd-alpine-ci-makecheckvalgrind | success | Make Check w/Valgrind |
prestwoj/iwd-alpine-ci-makecheck | success | Make Check |
prestwoj/iwd-ci-incremental_build | success | Incremental Build with patches |
prestwoj/iwd-alpine-ci-incremental_build | success | Incremental Build with patches |
prestwoj/iwd-ci-testrunner | success | test-runner PASS |
Hi James, On 1/13/23 15:24, James Prestwood wrote: > Under the following conditions IWD can accidentally trigger a second > roam scan while one is already in progress: > > - A low RSSI condition is met. This starts the roam rearm timer. > - A packet loss condition is met, which triggers a roam scan. > - The roam rearm timer fires and starts another roam scan while > also overwriting the first roam scan ID. > - Then, if IWD gets disconnected the overwritten roam scan gets > canceled, and the roam state is cleared which NULL's > station->connected_network. > - The initial roam scan results then come in with the assumption > that IWD is still connected which results in a crash trying to > reference station->connected_network. > > This can be fixed by adding a station_cannot_roam check in the rearm > timer. If IWD is already doing a roam scan station->preparing_roam > should be set which will cause it to return true and stop any further > action. > All applied, thanks. Regards, -Denis
diff --git a/src/station.c b/src/station.c index 4452e83e..1a69b98a 100644 --- a/src/station.c +++ b/src/station.c @@ -2701,6 +2701,28 @@ static void station_start_roam(struct station *station) station_roam_failed(station); } +static bool station_cannot_roam(struct station *station) +{ + const struct l_settings *config = iwd_get_config(); + bool disabled; + + /* + * Disable roaming with hardware that can roam automatically. Note this + * is now required for recent kernels which have CQM event support on + * this type of hardware (e.g. brcmfmac). + */ + if (wiphy_supports_firmware_roam(station->wiphy)) + return true; + + if (!l_settings_get_bool(config, "Scan", "DisableRoamingScan", + &disabled)) + disabled = false; + + return disabled || station->preparing_roam || + station->state == STATION_STATE_ROAMING || + station->state == STATION_STATE_FT_ROAMING; +} + static void station_roam_trigger_cb(struct l_timeout *timeout, void *user_data) { struct station *station = user_data; @@ -2710,6 +2732,9 @@ static void station_roam_trigger_cb(struct l_timeout *timeout, void *user_data) l_timeout_remove(station->roam_trigger_timeout); station->roam_trigger_timeout = NULL; + if (station_cannot_roam(station)) + return; + station_start_roam(station); } @@ -2735,28 +2760,6 @@ static void station_roam_timeout_rearm(struct station *station, int seconds) station, NULL); } -static bool station_cannot_roam(struct station *station) -{ - const struct l_settings *config = iwd_get_config(); - bool disabled; - - /* - * Disable roaming with hardware that can roam automatically. Note this - * is now required for recent kernels which have CQM event support on - * this type of hardware (e.g. brcmfmac). - */ - if (wiphy_supports_firmware_roam(station->wiphy)) - return true; - - if (!l_settings_get_bool(config, "Scan", "DisableRoamingScan", - &disabled)) - disabled = false; - - return disabled || station->preparing_roam || - station->state == STATION_STATE_ROAMING || - station->state == STATION_STATE_FT_ROAMING; -} - #define WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST (1 << 0) #define WNM_REQUEST_MODE_DISASSOCIATION_IMMINENT (1 << 2) #define WNM_REQUEST_MODE_TERMINATION_IMMINENT (1 << 3)