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
[email protected]
https://lists.connman.net/mailman/listinfo/connman