If there are pending D-Bus calls made inside supplicant code when wifi_remove() frees the wifi struct, wifi plugin callback functions may attempt to use already released memory when the calls complete.
Fixed by cancelling any outstanding supplicant calls in wifi_remove(). --- gsupplicant/gsupplicant.h | 2 ++ gsupplicant/supplicant.c | 15 +++++++++------ plugins/wifi.c | 2 ++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index a5ec405..7a3c843 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -172,6 +172,8 @@ typedef void (*GSupplicantInterfaceCallback) (int result, GSupplicantInterface *interface, void *user_data); +void g_supplicant_interface_cancel(GSupplicantInterface *interface); + int g_supplicant_interface_create(const char *ifname, const char *driver, const char *bridge, GSupplicantInterfaceCallback callback, diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 7b0f4d4..ea68433 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -1990,9 +1990,7 @@ static void interface_removed(DBusMessageIter *iter, void *user_data) return; interface = g_hash_table_lookup(interface_table, path); - SUPPLICANT_DBG("Cancelling any pending DBus calls"); - supplicant_dbus_method_call_cancel_all(interface); - supplicant_dbus_property_call_cancel_all(interface); + g_supplicant_interface_cancel(interface); g_hash_table_remove(interface_table, path); } @@ -2582,6 +2580,13 @@ static DBusHandlerResult g_supplicant_filter(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +void g_supplicant_interface_cancel(GSupplicantInterface *interface) +{ + SUPPLICANT_DBG("Cancelling any pending DBus calls"); + supplicant_dbus_method_call_cancel_all(interface); + supplicant_dbus_property_call_cancel_all(interface); +} + struct supplicant_regdom { GSupplicantCountryCallback callback; const char *alpha2; @@ -2980,9 +2985,7 @@ int g_supplicant_interface_remove(GSupplicantInterface *interface, if (!system_available) return -EFAULT; - SUPPLICANT_DBG("Cancelling any pending DBus calls"); - supplicant_dbus_method_call_cancel_all(interface); - supplicant_dbus_property_call_cancel_all(interface); + g_supplicant_interface_cancel(interface); data = dbus_malloc0(sizeof(*data)); if (!data) diff --git a/plugins/wifi.c b/plugins/wifi.c index ef4dd95..aaa5b00 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -313,6 +313,8 @@ static void wifi_remove(struct connman_device *device) g_supplicant_interface_set_data(wifi->interface, NULL); + g_supplicant_interface_cancel(wifi->interface); + if (wifi->scan_params) g_supplicant_free_scan_params(wifi->scan_params); -- 1.8.5.3 _______________________________________________ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman