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
This commit is contained in:
parent
eb023ff2c9
commit
f295349e26
@ -47,6 +47,9 @@ output_resource_destroy (struct wl_resource *res)
|
|||||||
MetaWaylandOutput *wayland_output;
|
MetaWaylandOutput *wayland_output;
|
||||||
|
|
||||||
wayland_output = wl_resource_get_user_data (res);
|
wayland_output = wl_resource_get_user_data (res);
|
||||||
|
if (!wayland_output)
|
||||||
|
return;
|
||||||
|
|
||||||
wayland_output->resources = g_list_remove (wayland_output->resources, res);
|
wayland_output->resources = g_list_remove (wayland_output->resources, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,14 +237,21 @@ static void
|
|||||||
meta_wayland_output_finalize (GObject *object)
|
meta_wayland_output_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
MetaWaylandOutput *wayland_output = META_WAYLAND_OUTPUT (object);
|
MetaWaylandOutput *wayland_output = META_WAYLAND_OUTPUT (object);
|
||||||
GList *resources;
|
GList *l;
|
||||||
|
|
||||||
/* Make sure the destructors don't mess with the list */
|
|
||||||
resources = wayland_output->resources;
|
|
||||||
wayland_output->resources = NULL;
|
|
||||||
|
|
||||||
wl_global_destroy (wayland_output->global);
|
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);
|
G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user