Skip to content

[Linux] Potential crash in FlAccessibleNode #188660

Closed

Description

@loic-sharma

Problem

During application exit, the FlEngine is finalized and its memory is freed. However, accessibility nodes can survive past this teardown because the external AT-SPI D-Bus accessibility bridge (libatk-bridge) maintains strong references to queried AtkObject elements. Accessibility nodes in this scenario have a dangling engine pointer.

FlAccessibleNode registers its weak-pointer notifies on itself instead of on the target object:

https://github.com/flutter/flutter/blob/master/engine/src/flutter/shell/platform/linux/fl_accessible_node.cc#L155-L158

g_object_add_weak_pointer(G_OBJECT(self),
reinterpret_cast<gpointer*>(&(priv->parent)));

g_object_add_weak_pointer(obj, loc) nulls *loc when obj is finalized, so registering on self provides zero protection against engine/parent destruction. priv->engine and priv->parent are therefore plain raw pointers. When the engine (or parent) is freed first — which is the normal ordering in fl_view_dispose — any subsequent AT-SPI call into the surviving node dereferences freed memory.

Suggested fix

The FlAccessibleNode should be refactored to use the thread-safe GWeakRef API for priv->engine, ensuring proper lifecycle management matching the rest of the embedder.

Potential bandaid fix...

diff --git a/engine/src/flutter/shell/platform/linux/fl_accessible_node.cc b/engine/src/flutter/shell/platform/linux/fl_accessible_node.cc
--- a/engine/src/flutter/shell/platform/linux/fl_accessible_node.cc
+++ b/engine/src/flutter/shell/platform/linux/fl_accessible_node.cc
@@ -154,7 +154,7 @@ static void fl_accessible_node_set_property(GObject* object,
     case PROP_ENGINE:
       g_assert(priv->engine == nullptr);
       priv->engine = FL_ENGINE(g_value_get_object(value));
-      g_object_add_weak_pointer(object,
+      g_object_add_weak_pointer(G_OBJECT(priv->engine),
                                 reinterpret_cast<gpointer*>(&priv->engine));
       break;
     case PROP_VIEW_ID:
@@ -173,12 +173,12 @@ static void fl_accessible_node_dispose(GObject* object) {
   FlAccessibleNodePrivate* priv = FL_ACCESSIBLE_NODE_GET_PRIVATE(object);

   if (priv->engine != nullptr) {
-    g_object_remove_weak_pointer(object,
+    g_object_remove_weak_pointer(G_OBJECT(priv->engine),
                                  reinterpret_cast<gpointer*>(&(priv->engine)));
     priv->engine = nullptr;
   }
   if (priv->parent != nullptr) {
-    g_object_remove_weak_pointer(object,
+    g_object_remove_weak_pointer(G_OBJECT(priv->parent),
                                  reinterpret_cast<gpointer*>(&(priv->parent)));
     priv->parent = nullptr;
   }
@@ -571,9 +571,14 @@ void fl_accessible_node_set_parent(FlAccessibleNode* self,
                                    gint index) {
   g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));
   FlAccessibleNodePrivate* priv = FL_ACCESSIBLE_NODE_GET_PRIVATE(self);
+  if (priv->parent != nullptr) {
+    g_object_remove_weak_pointer(G_OBJECT(priv->parent),
+                                 reinterpret_cast<gpointer*>(&(priv->parent)));
+    priv->parent = nullptr;
+  }
   priv->parent = parent;
   priv->index = index;
-  g_object_add_weak_pointer(G_OBJECT(self),
+  g_object_add_weak_pointer(G_OBJECT(parent),
                             reinterpret_cast<gpointer*>(&(priv->parent)));
 }

Internal bug

b/525521515

Activity

  1. added
    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)
    platform-linuxBuilding on or for Linux specifically
    c: fatal crashCrashes that terminate the process
    team-linuxOwned by the Linux platform team
    on Jun 26, 2026
  2. robert-ancell commented on Jun 28, 2026

    @robert-ancell
    Contributor

    Looks like this was a case that got missed when we migrated the other code from g_object_add_weak_pointer to GWeakRef.

  3. github-actions commented on Jul 14, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  4. locked as resolved and limited conversation to collaborators on Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)c: fatal crashCrashes that terminate the processplatform-linuxBuilding on or for Linux specificallyteam-linuxOwned by the Linux platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions