summaryrefslogtreecommitdiff
path: root/libgdm
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2020-09-25 15:27:47 -0400
committerRay Strode <halfline@gmail.com>2020-11-03 15:59:25 +0000
commit2615fb4ffe05b2640c15f4a9706796fe3b1376a9 (patch)
tree4181aae34a9b6b190ba129f03c522857cc5bcc33 /libgdm
parent1222ffdce0f175e32eb2d5cdd4c1f36232547442 (diff)
downloadgdm-2615fb4ffe05b2640c15f4a9706796fe3b1376a9.tar.gz
libgdm: Don't leak user verifier extensions on unlockwip/libgdm-proxy-leaks
GdmClient fails to free the hash table associated with user verifier extensions when the client is done with the user verifier. This commit ties the user verifier extensions to the user verifier instance associated with it, instead of storing the extensions directly in the client struct.
Diffstat (limited to 'libgdm')
-rw-r--r--libgdm/gdm-client.c70
1 files changed, 48 insertions, 22 deletions
diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 93817127..5ac73944 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -172,11 +172,13 @@ static void
maybe_complete_user_verifier_proxy_operation (GdmClient *client,
UserVerifierData *data)
{
+ GHashTable *user_verifier_extensions;
GHashTableIter iter;
gpointer key, value;
- if (client->user_verifier_extensions != NULL) {
- g_hash_table_iter_init (&iter, client->user_verifier_extensions);
+ user_verifier_extensions = g_object_get_data (G_OBJECT (client->user_verifier), "gdm-client-user-verifier-extensions");
+ if (user_verifier_extensions != NULL) {
+ g_hash_table_iter_init (&iter, user_verifier_extensions);
while (g_hash_table_iter_next (&iter, &key, &value)) {
if (value == NULL)
return;
@@ -191,19 +193,21 @@ on_user_verifier_choice_list_proxy_created (GObject *source,
GAsyncResult *result,
UserVerifierData *data)
{
+ GHashTable *user_verifier_extensions;
g_autoptr(GdmClient) client = NULL;
GdmUserVerifierChoiceList *choice_list;
g_autoptr(GError) error = NULL;
client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (data->task)));
+ user_verifier_extensions = g_object_get_data (G_OBJECT (data->user_verifier), "gdm-client-user-verifier-extensions");
choice_list = gdm_user_verifier_choice_list_proxy_new_finish (result, &error);
if (choice_list == NULL) {
g_debug ("Couldn't create UserVerifier ChoiceList proxy: %s", error->message);
- g_hash_table_remove (client->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name);
+ g_hash_table_remove (user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name);
} else {
- g_hash_table_replace (client->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name, choice_list);
+ g_hash_table_replace (user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name, choice_list);
}
maybe_complete_user_verifier_proxy_operation (client, data);
@@ -215,6 +219,7 @@ on_user_verifier_extensions_enabled (GdmUserVerifier *user_verifier,
UserVerifierData *data)
{
g_autoptr(GdmClient) client = NULL;
+ GHashTable *user_verifier_extensions;
GCancellable *cancellable;
GDBusConnection *connection;
g_autoptr(GError) error = NULL;
@@ -222,6 +227,7 @@ on_user_verifier_extensions_enabled (GdmUserVerifier *user_verifier,
client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (data->task)));
cancellable = g_task_get_cancellable (data->task);
+ user_verifier_extensions = g_object_get_data (G_OBJECT (user_verifier), "gdm-client-user-verifier-extensions");
gdm_user_verifier_call_enable_extensions_finish (user_verifier, result, &error);
@@ -236,11 +242,11 @@ on_user_verifier_extensions_enabled (GdmUserVerifier *user_verifier,
for (i = 0; client->enabled_extensions[i] != NULL; i++) {
g_debug ("Enabled extensions[%lu] = %s", i, client->enabled_extensions[i]);
- g_hash_table_insert (client->user_verifier_extensions, client->enabled_extensions[i], NULL);
+ g_hash_table_insert (user_verifier_extensions, client->enabled_extensions[i], NULL);
if (strcmp (client->enabled_extensions[i],
gdm_user_verifier_choice_list_interface_info ()->name) == 0) {
- g_hash_table_insert (client->user_verifier_extensions, client->enabled_extensions[i], NULL);
+ g_hash_table_insert (user_verifier_extensions, client->enabled_extensions[i], NULL);
gdm_user_verifier_choice_list_proxy_new (connection,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
@@ -251,12 +257,12 @@ on_user_verifier_extensions_enabled (GdmUserVerifier *user_verifier,
data);
} else {
g_debug ("User verifier extension %s is unsupported", client->enabled_extensions[i]);
- g_hash_table_remove (client->user_verifier_extensions,
+ g_hash_table_remove (user_verifier_extensions,
client->enabled_extensions[i]);
}
}
- if (g_hash_table_size (client->user_verifier_extensions) == 0) {
+ if (g_hash_table_size (user_verifier_extensions) == 0) {
g_debug ("No supported user verifier extensions");
complete_user_verifier_proxy_operation (client, data);
}
@@ -278,6 +284,7 @@ on_user_verifier_proxy_created (GObject *source,
gpointer user_data)
{
g_autoptr(GdmClient) self = NULL;
+ GHashTable *user_verifier_extensions;
GCancellable *cancellable = NULL;
g_autoptr(GdmUserVerifier) user_verifier = NULL;
g_autoptr(GTask) task = user_data;
@@ -300,11 +307,15 @@ on_user_verifier_proxy_created (GObject *source,
return;
}
- self->user_verifier_extensions = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- (GDestroyNotify)
- free_interface_skeleton);
+ user_verifier_extensions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify)
+ free_interface_skeleton);
+ g_object_set_data_full (G_OBJECT (user_verifier),
+ "gdm-client-user-verifier-extensions",
+ user_verifier_extensions,
+ (GDestroyNotify) g_hash_table_unref);
cancellable = g_task_get_cancellable (task);
gdm_user_verifier_call_enable_extensions (user_verifier,
(const char * const *)
@@ -662,13 +673,19 @@ gdm_client_get_user_verifier_sync (GdmClient *client,
(gpointer *)
&client->user_verifier);
if (client->enabled_extensions != NULL) {
+ GHashTable *user_verifier_extensions;
gboolean res;
- client->user_verifier_extensions = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- (GDestroyNotify)
- free_interface_skeleton);
+ user_verifier_extensions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify)
+ free_interface_skeleton);
+ g_object_set_data_full (G_OBJECT (client->user_verifier),
+ "gdm-client-user-verifier-extensions",
+ user_verifier_extensions,
+ (GDestroyNotify) g_hash_table_unref);
+
res = gdm_user_verifier_call_enable_extensions_sync (client->user_verifier,
(const char * const *)
client->enabled_extensions,
@@ -688,7 +705,7 @@ gdm_client_get_user_verifier_sync (GdmClient *client,
cancellable,
NULL);
if (choice_list_interface != NULL)
- g_hash_table_insert (client->user_verifier_extensions, client->enabled_extensions[i], choice_list_interface);
+ g_hash_table_insert (user_verifier_extensions, client->enabled_extensions[i], choice_list_interface);
}
}
}
@@ -790,12 +807,18 @@ gdm_client_get_user_verifier_finish (GdmClient *client,
if (user_verifier == NULL)
return NULL;
- client->user_verifier = user_verifier;
+ if (client->user_verifier != NULL) {
+ g_object_remove_weak_pointer (G_OBJECT (client->user_verifier),
+ (gpointer *)
+ &client->user_verifier);
+ }
g_object_add_weak_pointer (G_OBJECT (client->user_verifier),
(gpointer *)
&client->user_verifier);
+ client->user_verifier = user_verifier;
+
return user_verifier;
}
@@ -812,10 +835,13 @@ gdm_client_get_user_verifier_finish (GdmClient *client,
GdmUserVerifierChoiceList *
gdm_client_get_user_verifier_choice_list (GdmClient *client)
{
- if (client->user_verifier_extensions == NULL)
+ GHashTable *user_verifier_extensions;
+
+ user_verifier_extensions = g_object_get_data (G_OBJECT (client->user_verifier), "gdm-client-user-verifier-extensions");
+ if (user_verifier_extensions == NULL)
return NULL;
- return g_hash_table_lookup (client->user_verifier_extensions,
+ return g_hash_table_lookup (user_verifier_extensions,
gdm_user_verifier_choice_list_interface_info ()->name);
}