diff options
author | Olivier Fourdan <ofourdan@redhat.com> | 2018-07-27 16:32:31 +0000 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2019-01-14 10:06:45 -0500 |
commit | 733ab3b2bc34fac013d2a6e5b81443b7046acae9 (patch) | |
tree | 93cc715cb81e7d94a99e1e4ab2f7c077be7815ce | |
parent | a208d7c33e3902eeeae72e0e8789b7ddf346823f (diff) | |
download | mutter-733ab3b2bc34fac013d2a6e5b81443b7046acae9.tar.gz |
wayland: Nullify monitor resources when updating outputs
If a client asks for xdg-output before we have set the output's logical
monitor, we would end up crashing with a NULL pointer dereference.
Make sure we clear the resource's user data when marking an output as
inert on monitor change so that we don't end up with a Wayland output
without a logical monitor.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/194
(cherry picked from commit 48eaa36d41bb88d4831e40e9c3ef3c7afda195bc)
-rw-r--r-- | src/wayland/meta-wayland-outputs.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c index 509527d38..bc67b90be 100644 --- a/src/wayland/meta-wayland-outputs.c +++ b/src/wayland/meta-wayland-outputs.c @@ -365,12 +365,38 @@ meta_wayland_output_new (MetaWaylandCompositor *compositor, } static void -nullify_logical_monitor (gpointer key, - gpointer value, - gpointer data) +make_output_resources_inert (MetaWaylandOutput *wayland_output) +{ + GList *l; + + 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); + wayland_output->resources = NULL; + + for (l = wayland_output->xdg_output_resources; l; l = l->next) + { + struct wl_resource *xdg_output_resource = l->data; + + wl_resource_set_user_data (xdg_output_resource, NULL); + } + g_list_free (wayland_output->xdg_output_resources); + wayland_output->xdg_output_resources = NULL; +} + +static void +make_output_inert (gpointer key, + gpointer value, + gpointer data) { MetaWaylandOutput *wayland_output = value; + wayland_output->logical_monitor = NULL; + make_output_resources_inert (wayland_output); } static gboolean @@ -420,7 +446,7 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor, wayland_output); } - g_hash_table_foreach (compositor->outputs, nullify_logical_monitor, NULL); + g_hash_table_foreach (compositor->outputs, make_output_inert, NULL); g_timeout_add_seconds (10, delayed_destroy_outputs, compositor->outputs); return new_table; @@ -449,23 +475,7 @@ meta_wayland_output_finalize (GObject *object) /* 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); - - for (l = wayland_output->xdg_output_resources; l; l = l->next) - { - struct wl_resource *xdg_output_resource = l->data; - - wl_resource_set_user_data (xdg_output_resource, NULL); - } - - g_list_free (wayland_output->xdg_output_resources); + make_output_resources_inert (wayland_output); G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object); } |