GAS: Remove all radio works before calling gas_query_deinit()
authorIlan Peer <ilan.peer@intel.com>
Mon, 1 Jun 2015 10:38:10 +0000 (13:38 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 10 Jun 2015 23:57:34 +0000 (02:57 +0300)
Remove all gas-query radio works before calling gas_query_deinit()
as gas_query_deinit() flow frees the query context, which might
be later be accessed from the radio work callback (and result
with unexpected behavior, e.g., segmentation fault).

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
wpa_supplicant/wpa_supplicant.c

index 05f4808..e833c3a 100644 (file)
@@ -493,6 +493,16 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
 
        wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
 
+       /*
+        * Need to remove any pending gas-query radio work before the
+        * gas_query_deinit() call because gas_query::work has not yet been set
+        * for works that have not been started. gas_query_free() will be unable
+        * to cancel such pending radio works and once the pending gas-query
+        * radio work eventually gets removed, the deinit notification call to
+        * gas_query_start_cb() would result in dereferencing freed memory.
+        */
+       if (wpa_s->radio)
+               radio_remove_works(wpa_s, "gas-query", 0);
        gas_query_deinit(wpa_s->gas);
        wpa_s->gas = NULL;