1
0
Fork 0

wayland/subsurface: Hold sibling surface reference in placement ops

It was possible for the sibling surface to be already destroyed in
meta_wayland_transaction_add_placement_surfaces, in which case
g_object_ref would return NULL for it, and
meta_wayland_transaction_commit would then crash dereferencing a NULL
surface pointer.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3462
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3725>
This commit is contained in:
Michel Dänzer 2024-04-30 15:35:14 +02:00 committed by Sebastian Wick
parent 3155cf514c
commit b67f94ca7e
3 changed files with 14 additions and 3 deletions

View file

@ -317,7 +317,6 @@ get_subsurface_placement_op (MetaWaylandSurface *surface,
GNode *sibling_node;
op->placement = placement;
op->sibling = sibling;
op->surface = surface;
g_node_unlink (surface->committed_state.subsurface_branch_node);
@ -325,6 +324,8 @@ get_subsurface_placement_op (MetaWaylandSurface *surface,
if (!sibling)
return op;
op->sibling = g_object_ref (sibling);
if (sibling == parent)
sibling_node = parent->committed_state.subsurface_leaf_node;
else
@ -347,6 +348,13 @@ get_subsurface_placement_op (MetaWaylandSurface *surface,
return op;
}
void
meta_wayland_subsurface_destroy_placement_op (MetaWaylandSubsurfacePlacementOp *op)
{
g_clear_object (&op->sibling);
g_free (op);
}
static void
subsurface_place (struct wl_client *client,
struct wl_resource *resource,
@ -410,7 +418,7 @@ meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
if (op->surface == surface)
{
g_free (link->data);
meta_wayland_subsurface_destroy_placement_op (op);
*list = g_slist_delete_link (*list, link);
}
else

View file

@ -44,6 +44,8 @@ void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
int parent_y,
MtkRectangle *out_geometry);
void meta_wayland_subsurface_destroy_placement_op (MetaWaylandSubsurfacePlacementOp *op);
void meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
MetaWaylandSurface *surface);

View file

@ -493,7 +493,8 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
wl_resource_destroy (cb->resource);
if (state->subsurface_placement_ops)
g_slist_free_full (state->subsurface_placement_ops, g_free);
g_slist_free_full (state->subsurface_placement_ops,
(GDestroyNotify) meta_wayland_subsurface_destroy_placement_op);
meta_wayland_surface_state_discard_presentation_feedback (state);
}