summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2014-08-28 09:10:37 +0200
committerJiří Klimeš <jklimes@redhat.com>2014-08-28 09:44:04 +0200
commitf6b4ab7d3b86739198ab73db180aed01dfb1c65b (patch)
tree0350ac6fcf99810c7d4117f3201515dadc699e13
parent94758eb68824f10df2fdaaa323bec1488c60b4cc (diff)
settings: fix a crash in emit_updated() accessing invalid pointer
by disconnecting signal handlers in dispose(). Commit 6a19e68a moved nm_connection_clear_secrets() from plugins' finalize() to NMSettingsConnection's dispose(). But clearing secrets emits "changed" signal which cause changed_cb() to be called and emit_updated() scheduled. And emit_updated() was called later after finalize() on released object. The crash can be invoked by having two keyfile connection files with the same uuid in them. Backtrace: (NetworkManager:12262): GLib-GObject-WARNING **: attempt to retrieve private data for invalid type 'NMSettingsConnection' Program received signal SIGSEGV, Segmentation fault. emit_updated (self=0xf38dd0 [NMSettingConnection]) at settings/nm-settings-connection.c:401 401 NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->updated_idle_id = 0; (gdb) bt #0 emit_updated (self=0xf38dd0 [NMSettingConnection]) at settings/nm-settings-connection.c:401 #1 0x0000003c49647825 in g_main_dispatch (context=0x785970) at gmain.c:2539 #2 g_main_context_dispatch (context=context@entry=0x785970) at gmain.c:3075 #3 0x0000003c49647b58 in g_main_context_iterate (context=0x785970, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3146 #4 0x0000003c49647f52 in g_main_loop_run (loop=0x7857c0) at gmain.c:3340 #5 0x000000000042d4e9 in main (argc=1, argv=0x7fffffffe508) at main.c:679
-rw-r--r--src/settings/nm-settings-connection.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 3a2b5ac20e..c534461959 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -2044,6 +2044,13 @@ dispose (GObject *object)
priv->updated_idle_id = 0;
}
+ /* Disconnect handlers.
+ * changed_cb() has to be disconnected *before* nm_connection_clear_secrets(),
+ * because nm_connection_clear_secrets() emits NM_CONNECTION_CHANGED signal.
+ */
+ g_signal_handlers_disconnect_by_func (self, G_CALLBACK (secrets_cleared_cb), NULL);
+ g_signal_handlers_disconnect_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE));
+
nm_connection_clear_secrets (NM_CONNECTION (self));
g_clear_object (&priv->system_secrets);
g_clear_object (&priv->agent_secrets);