From f295349e263d4c3a70905d2e16e32002f42d6777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 1 Jul 2015 13:18:45 +0800 Subject: [PATCH] wayland: Don't crash if wl_output resource is destroyed after being removed Previously a MetaWaylandOutput could be removed from the current outputs table (by being unplugged for example). This would result in the global object being removed and the MetaWaylandOutput instance freed, but the wl_resource destructor would still try to remove itself from the list of resources. Trying to do this, it'd try to access its user data pointer which would point to the freed MetaWaylandOutput instance, and as a result crash when trying to manipulate the freed data. https://bugzilla.gnome.org/show_bug.cgi?id=744453 --- src/wayland/meta-wayland-outputs.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c index bdd1c6839..1a7d16efa 100644 --- a/src/wayland/meta-wayland-outputs.c +++ b/src/wayland/meta-wayland-outputs.c @@ -47,6 +47,9 @@ output_resource_destroy (struct wl_resource *res) MetaWaylandOutput *wayland_output; wayland_output = wl_resource_get_user_data (res); + if (!wayland_output) + return; + wayland_output->resources = g_list_remove (wayland_output->resources, res); } @@ -234,14 +237,21 @@ static void meta_wayland_output_finalize (GObject *object) { MetaWaylandOutput *wayland_output = META_WAYLAND_OUTPUT (object); - GList *resources; - - /* Make sure the destructors don't mess with the list */ - resources = wayland_output->resources; - wayland_output->resources = NULL; + GList *l; wl_global_destroy (wayland_output->global); - g_list_free (resources); + + /* Make sure the wl_output destructor doesn't try to access MetaWaylandOutput + * after we have freed it. + */ + for (l = wayland_output->resources; l; l = l->next) + { + struct wl_resource *output_resource = l->data; + + wl_resource_set_user_data (output_resource, NULL); + } + + g_list_free (wayland_output->resources); G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object); }