summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index 00f0c307ee..6fa2ee5c31 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -144,6 +144,7 @@ typedef struct {
DBusGProxy *proxy;
NMCallStore *store;
DBusGProxyCall *call;
+ gboolean disposing;
} NMSupplicantInfo;
static NMSupplicantInfo *
@@ -164,10 +165,11 @@ nm_supplicant_info_new (NMSupplicantInterface *interface,
static void
nm_supplicant_info_set_call (NMSupplicantInfo *info, DBusGProxyCall *call)
{
- if (call) {
- nm_call_store_add (info->store, G_OBJECT (info->proxy), (gpointer) call);
- info->call = call;
- }
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (call != NULL);
+
+ nm_call_store_add (info->store, G_OBJECT (info->proxy), (gpointer) call);
+ info->call = call;
}
static void
@@ -175,13 +177,25 @@ nm_supplicant_info_destroy (gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- if (info->call)
- nm_call_store_remove (info->store, G_OBJECT (info->proxy), info->call);
+ /* Guard against double-disposal; since DBusGProxy doesn't guard against
+ * double-disposal, we could infinite loop here if we're in the middle of
+ * some wpa_supplicant D-Bus calls. When the supplicant dies we'll dispose
+ * of the proxy, which kills all its pending calls, which brings us here.
+ * Then when we unref the proxy here, its dispose() function will get called
+ * again, and we get right back here until we segfault because our callstack
+ * is too long.
+ */
+ if (!info->disposing) {
+ info->disposing = TRUE;
- g_object_unref (info->proxy);
- g_object_unref (info->interface);
+ if (info->call)
+ nm_call_store_remove (info->store, G_OBJECT (info->proxy), info->call);
- g_slice_free (NMSupplicantInfo, info);
+ g_object_unref (info->proxy);
+ g_object_unref (info->interface);
+
+ g_slice_free (NMSupplicantInfo, info);
+ }
}