SIGN IN SIGN UP
facebook / react-native UNCLAIMED

A framework for building native applications using React

0 0 0 C++

Fix SIGSEGV in ShadowNode::getTag() caused by use-after-free in findShadowNodeByTag_DEPRECATED (#55751)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55751

A SIGSEGV crash is occurring in production when `ShadowNode::getTag()` is called on a destroyed ShadowNode during focus navigation (`FabricUIManagerBinding::findNextFocusableElement`).

**Root cause**: `UIManager::findShadowNodeByTag_DEPRECATED` captures a **raw pointer** to the root shadow node inside a `tryCommit` callback, then dereferences it **after the lock is released**. Another thread can commit a new tree in between, destroying the old root and leaving a dangling pointer:

```
tryCommit([&](const RootShadowNode& old) {
    rootShadowNode = &old;   // capture raw address
    return nullptr;           // cancel commit, release lock
}, {});
// !!! LOCK RELEASED — another thread can replace + destroy the old root
rootShadowNode->getChildren();  // use-after-free → SIGSEGV
```

**Fix**: Replace the `tryCommit` + raw pointer pattern with `ShadowTree::getCurrentRevision()`, which returns a `ShadowTreeRevision` by value containing a `shared_ptr<const RootShadowNode>`. The `shared_ptr` copy keeps the root node alive for the entire traversal.

**Why the old root gets destroyed**: After a commit, the old root's `shared_ptr` in `currentRevision_` is replaced. The `MountingCoordinator::push()` also overwrites `lastRevision_`. If no other holder remains (e.g. `baseRevision_` holds an earlier root), the old root's refcount drops to 0 and it is freed — while the finder thread may still hold a raw pointer to it.

Changelog: [Internal]

Reviewed By: mdvacca, javache

Differential Revision: D94376636

fbshipit-source-id: 07882beed246d61c1476f7f7790586c60a1debdb
P
Peter Abbondanzo committed
7d2d3a2106be10f9a09ec78616b9981a01b5b2f9
Parent: ec29c29
Committed by meta-codesync[bot] <215208954+meta-codesync[bot]@users.noreply.github.com> on 2/26/2026, 4:14:25 PM