From 91a95dd9165023966b4377ad49cd8342eab5d776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Thu, 21 Nov 2013 13:40:04 +0100 Subject: [PATCH] agents: fix crash in nm_secret_agent_cancel_secrets() (rh #922855) When request for getting secrets is being freed in request_free(), cancel_callback is get_cancel_cb(). It uses parent->current as a secret agent object. However, this object can be already freed and thus there is a problem getting priv in nm_secret_agent_cancel_secrets: g_return_if_fail (self != NULL); priv = NM_SECRET_AGENT_GET_PRIVATE (self); (gdb) p self $66 = (NMSecretAgent *) 0x7fae9afd42e0 (gdb) p *self $67 = {parent = {g_type_instance = {g_class = 0x0}, ref_count = 0, qdata = 0x0}} #0 nm_secret_agent_cancel_secrets (self=0x7fae9afd42e0, call=0x1) at settings/nm-secret-agent.c:325 #1 0x00007fae9a774882 in request_free (req=0x7fae9afc48f0) at settings/nm-agent-manager.c:496 #2 0x00007fae967b251a in g_hash_table_remove_internal (hash_table=0x7fae9aefdf00, key=0x2, notify=1) at ghash.c:1276 #3 0x00007fae9a72b340 in dispose (object=0x7fae9af77200) at nm-activation-request.c:446 #4 0x00007fae96cbeee8 in g_object_unref (_object=0x7fae9af77200) at gobject.c:3160 #5 0x00007fae9a73d87c in _active_connection_cleanup (user_data=) at nm-manager.c:359 #6 0x00007fae967c32a6 in g_main_dispatch (context=0x7fae9aedb180) at gmain.c:3066 #7 g_main_context_dispatch (context=context@entry=0x7fae9aedb180) at gmain.c:3642 #8 0x00007fae967c3628 in g_main_context_iterate (context=0x7fae9aedb180, block=block@entry=1, dispatch=dispatch@entry=1, self=) at gmain.c:3713 #9 0x00007fae967c3a3a in g_main_loop_run (loop=0x7fae9aedb860) at gmain.c:3907 So we need to ref() 'agent' when adding it to pending list, so that the object is not freed if the secret agent unregisters and is removed. Test case: 1. run NM and nm-applet 2. activate a Wi-Fi network 3. nm-applet will ask for a password; ignore the popup window and kill nm-applet 4. start nm-applet again 5. click the same Wi-Fi network in nm-applet 6. NM will experience problems in nm_secret_agent_cancel_secrets() or crashes (the procedure may not be 100%, but reproduces most of the time) https://bugzilla.redhat.com/show_bug.cgi?id=922855 --- src/settings/nm-agent-manager.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 8644293db5..7fb8aea29a 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -492,7 +492,7 @@ request_free (Request *req) g_free (req->detail); g_free (req->verb); - g_slist_free (req->pending); + g_slist_free_full (req->pending, g_object_unref); g_slist_free (req->asked); memset (req, 0, sizeof (Request)); g_free (req); @@ -582,7 +582,7 @@ request_add_agent (Request *req, /* Add this agent to the list, preferring active sessions */ req->pending = g_slist_insert_sorted_with_data (req->pending, - agent, + g_object_ref (agent), (GCompareDataFunc) agent_compare_func, session_monitor); } @@ -607,6 +607,8 @@ request_next_agent (Request *req) if (req->pending) { /* Send the request to the next agent */ req->current_call_id = NULL; + if (req->current) + g_object_unref (req->current); req->current = req->pending->data; req->pending = g_slist_remove (req->pending, req->current);