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>
(cherry picked from commit b67f94ca7e
)
This commit is contained in:
parent
003cb6d5ce
commit
519321252a
3 changed files with 14 additions and 3 deletions
|
@ -317,7 +317,6 @@ get_subsurface_placement_op (MetaWaylandSurface *surface,
|
||||||
GNode *sibling_node;
|
GNode *sibling_node;
|
||||||
|
|
||||||
op->placement = placement;
|
op->placement = placement;
|
||||||
op->sibling = sibling;
|
|
||||||
op->surface = surface;
|
op->surface = surface;
|
||||||
|
|
||||||
g_node_unlink (surface->committed_state.subsurface_branch_node);
|
g_node_unlink (surface->committed_state.subsurface_branch_node);
|
||||||
|
@ -325,6 +324,8 @@ get_subsurface_placement_op (MetaWaylandSurface *surface,
|
||||||
if (!sibling)
|
if (!sibling)
|
||||||
return op;
|
return op;
|
||||||
|
|
||||||
|
op->sibling = g_object_ref (sibling);
|
||||||
|
|
||||||
if (sibling == parent)
|
if (sibling == parent)
|
||||||
sibling_node = parent->committed_state.subsurface_leaf_node;
|
sibling_node = parent->committed_state.subsurface_leaf_node;
|
||||||
else
|
else
|
||||||
|
@ -347,6 +348,13 @@ get_subsurface_placement_op (MetaWaylandSurface *surface,
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_subsurface_destroy_placement_op (MetaWaylandSubsurfacePlacementOp *op)
|
||||||
|
{
|
||||||
|
g_clear_object (&op->sibling);
|
||||||
|
g_free (op);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
subsurface_place (struct wl_client *client,
|
subsurface_place (struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
|
@ -410,7 +418,7 @@ meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
|
||||||
|
|
||||||
if (op->surface == surface)
|
if (op->surface == surface)
|
||||||
{
|
{
|
||||||
g_free (link->data);
|
meta_wayland_subsurface_destroy_placement_op (op);
|
||||||
*list = g_slist_delete_link (*list, link);
|
*list = g_slist_delete_link (*list, link);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -44,6 +44,8 @@ void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||||
int parent_y,
|
int parent_y,
|
||||||
MtkRectangle *out_geometry);
|
MtkRectangle *out_geometry);
|
||||||
|
|
||||||
|
void meta_wayland_subsurface_destroy_placement_op (MetaWaylandSubsurfacePlacementOp *op);
|
||||||
|
|
||||||
void meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
|
void meta_wayland_subsurface_drop_placement_ops (MetaWaylandSurfaceState *state,
|
||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface);
|
||||||
|
|
||||||
|
|
|
@ -493,7 +493,8 @@ meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
|
||||||
wl_resource_destroy (cb->resource);
|
wl_resource_destroy (cb->resource);
|
||||||
|
|
||||||
if (state->subsurface_placement_ops)
|
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);
|
meta_wayland_surface_state_discard_presentation_feedback (state);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue