summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2018-07-27 18:32:31 +0200
committerOlivier Fourdan <ofourdan@redhat.com>2018-07-30 09:22:12 +0200
commit48eaa36d41bb88d4831e40e9c3ef3c7afda195bc (patch)
treee98916024b83beb5a34bb225f540350c25f7bc99
parent6e953e2725d5d5b10d14c7bd479bd99f6853addc (diff)
downloadmutter-48eaa36d41bb88d4831e40e9c3ef3c7afda195bc.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
-rw-r--r--src/wayland/meta-wayland-outputs.c52
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);
}