From 5cfbe2528cec2f3d4f18a1556e8f830e81da99fc Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Thu, 20 Jun 2024 17:05:42 -0300 Subject: [PATCH] clutter/cally-actor: Ensure accessible lives long enough Inside the "if (clutter_actor_has_accessible (actor))" condition, the 'atk_child' variable is set and a signal is emitted on it. There is a classic ref/unref dance around the signal to guarantee that 'atk_child' won't be destroyed. However, this ref/unref dance doesn't work, because the unref is done *before* the 'atk_child' variable is used again. So if this was the last reference to it, it would have been destroyed in the unref call, then used for another signal emission a few lines down. That's a use-after-free. Fix that by declaring the 'atk_child' variable with g_autoptr. This delays the unref until the very end of the function, and is NULL safe. Also add a sneaky assertion, just for extra safety. Part-of: --- clutter/clutter/cally/cally-actor.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c index cdf001614..0d207b0f0 100644 --- a/clutter/clutter/cally/cally-actor.c +++ b/clutter/clutter/cally/cally-actor.c @@ -474,9 +474,9 @@ cally_actor_remove_actor (ClutterActor *container, ClutterActor *actor, gpointer data) { + g_autoptr (AtkObject) atk_child = NULL; AtkPropertyValues values = { NULL }; AtkObject *atk_parent = NULL; - AtkObject *atk_child = NULL; CallyActorPrivate *priv = NULL; gint index; @@ -489,15 +489,16 @@ cally_actor_remove_actor (ClutterActor *container, { atk_child = clutter_actor_get_accessible (actor); + g_assert (ATK_IS_OBJECT (atk_child)); + g_object_ref (atk_child); + g_value_init (&values.old_value, G_TYPE_POINTER); g_value_set_pointer (&values.old_value, atk_parent); values.property_name = "accessible-parent"; - g_object_ref (atk_child); g_signal_emit_by_name (atk_child, "property_change::accessible-parent", &values, NULL); - g_object_unref (atk_child); } priv = cally_actor_get_instance_private (CALLY_ACTOR (atk_parent));