From 76207194d15ebc50ca6d247da78a03de9c34f47f Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Thu, 21 Dec 2017 20:36:49 +0100 Subject: [PATCH] shared/compat: Fix memory handling of nm_setting_vpn_get_*_keys (v2) The compat implementations return a (transfer none) strv instead of a (transfer container) one. This has caused double frees in nm-applet: https://bugs.archlinux.org/task/56772 We still need to copy the keys because nm_setting_vpn_foreach_* provides us with copies that are freed after the iteration. Fix this by handing out a duplicate of the array. Fixes: 272439cb2077a889485dd195bb6b99ca91d3e3bf https://mail.gnome.org/archives/networkmanager-list/2017-December/msg00070.html --- shared/nm-utils/nm-compat.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/shared/nm-utils/nm-compat.c b/shared/nm-utils/nm-compat.c index 22ab675de8..b470e804c0 100644 --- a/shared/nm-utils/nm-compat.c +++ b/shared/nm-utils/nm-compat.c @@ -44,25 +44,32 @@ _get_keys (NMSettingVpn *setting, nm_assert (NM_IS_SETTING_VPN (setting)); - a = g_ptr_array_new (); + if (is_secrets) + len = nm_setting_vpn_get_num_secrets (setting); + else + len = nm_setting_vpn_get_num_data_items (setting); + + a = g_ptr_array_new_full (len + 1, (GDestroyNotify) g_free); + if (is_secrets) nm_setting_vpn_foreach_secret (setting, _get_keys_cb, a); else nm_setting_vpn_foreach_data_item (setting, _get_keys_cb, a); + len = a->len; - if (a->len) { + if (len) { g_ptr_array_sort (a, nm_strcmp_p); g_ptr_array_add (a, NULL); - keys = (const char **) g_ptr_array_free (g_steal_pointer (&a), FALSE); + keys = g_memdup (a->pdata, a->len * sizeof *keys); /* we need to cache the keys *somewhere*. */ g_object_set_qdata_full (G_OBJECT (setting), is_secrets ? NM_CACHED_QUARK ("libnm._nm_setting_vpn_get_secret_keys") : NM_CACHED_QUARK ("libnm._nm_setting_vpn_get_data_keys"), - keys, - (GDestroyNotify) g_strfreev); + g_ptr_array_ref (a), + (GDestroyNotify) g_ptr_array_unref); } NM_SET_OUT (out_length, len);