Bug 51842

Summary: mission-control try to access freed memory (valgrind)
Product: Telepathy Reporter: Laurent Bigonville <bigon>
Component: mission-controlAssignee: Telepathy bugs list <telepathy-bugs>
Status: RESOLVED FIXED QA Contact: Telepathy bugs list <telepathy-bugs>
Severity: normal    
Priority: medium CC: xclaesse
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Valgrind
McdAccountManagerDefault: Fix a possible double free

Description Laurent Bigonville 2012-07-07 14:47:46 UTC
Created attachment 63953 [details]
Valgrind

Hi,

I've several crash that are affecting me quite often (bug #51559 and #51813)

I was running MC in valgrind and it seems it tries to access freed memory in several occasions
Comment 1 Xavier Claessens 2012-07-09 10:25:56 UTC
*** Bug 51454 has been marked as a duplicate of this bug. ***
Comment 2 Xavier Claessens 2012-07-09 10:31:46 UTC
I've understood how this can happen:
in mcd-account-manager-default.c::_delete_from_keyring() it does:
      gchar *removed = g_strdup (account);
      g_hash_table_insert (amd->removed_accounts, removed, removed);

So what happens if the account is already in the hash table? Doc says:
"""
If the key already exists in the GHashTable its current value is replaced with the new value. If you supplied a value_destroy_func when creating the GHashTable, the old value is freed using that function. If you supplied a key_destroy_func when creating the GHashTable, the passed key is freed using that function.
"""

Since @removed is passed both as value and key, it gets inserted as value but freed as key => we get a freed string as value!!
Comment 3 Xavier Claessens 2012-07-09 10:38:55 UTC
Created attachment 64015 [details] [review]
McdAccountManagerDefault: Fix a possible double free

If the account is already in the hashtable, g_hash_table_insert()
will set @removed as value, but free it since the key already in
the table is kept.
Comment 4 Xavier Claessens 2012-07-09 10:41:03 UTC
Note that we could use g_hash_table_add() but that's new in glib 2.32 and MC still depends on 2.30. In master that's certainly OK, but probably not for backporting in stable branch.
Comment 5 Jonny Lamb 2012-07-09 10:48:16 UTC
Can you write a test for this perchance?
Comment 6 Laurent Bigonville 2012-07-09 11:28:47 UTC
Doesn't it sound weird that MC is actually calling _delete_from_keyring() function from mcd_account_connection_self_nickname_changed_cb() ?
Comment 7 Xavier Claessens 2012-07-09 11:33:26 UTC
Right, that looks suspicious. Also I'm starting to wonder if I really fixed this issue.

As explained above, we can end with freed strings as value in the hash table, but the value is never used... only the key is. And I don't see how the key could be invalid.
Comment 8 Xavier Claessens 2012-07-09 13:52:56 UTC
Ok, it continuously wants to remove *GOA* accounts from default storage (keyring and .mission-control/accounts/accounts.cfg), because they are not stored there.

My patch really fix the issue, I was able reproduce the valgrind logs and with the patch I can't anymore.

I've absolutely no idea how to test this behaviour though, that involves having accounts on other storage than the default one... and even then you need valgrind to catch the problem, it does not always crash.
Comment 9 Jonny Lamb 2012-07-09 14:05:57 UTC
MC already has a test account storage -- the diverted plugin.

All accounts will be saved in the non-default account storage unless the account parameter starts with 'dontdivert'.
Comment 10 Xavier Claessens 2012-07-11 10:12:26 UTC
I couldn't reproduce this in a unit test. I've spent enough time on this 1 line fix, if someone knows how MC tests works please do it :-)
Comment 11 Laurent Bigonville 2012-07-17 10:08:38 UTC
*** Bug 51813 has been marked as a duplicate of this bug. ***

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.