Skip to content

Add guards around nativeProps usage to prevent race conditions#52646

Open
OrfeasZ wants to merge 1 commit into
react:mainfrom
OrfeasZ:fix/clone-prop-update-race-condition
Open

Add guards around nativeProps usage to prevent race conditions#52646
OrfeasZ wants to merge 1 commit into
react:mainfrom
OrfeasZ:fix/clone-prop-update-race-condition

Conversation

@OrfeasZ

@OrfeasZ OrfeasZ commented Jul 16, 2025

Copy link
Copy Markdown

Summary:

Some third-party libraries, like react-native-reanimated, can clone nodes in a different thread while react-native is calling setNativeProps_DEPRECATED. This results in a race condition, where a stale pointer to nativeProps_DEPRECATED can be accessed, resulting in a crash. This usually manifests as a EXC_BAD_ACCESS crash on iOS. On Android it seems more rare. We've added a lock around accesses to nativeProps_DEPRECATED, but alternative options of fixing this can be considered too.

For more information see software-mansion/react-native-reanimated#7666

Changelog:

[INTERNAL] [FIXED] - Fixed crashes caused by race conditions when third-party libraries clone the shadow dom from a different thread

Test Plan:

Due to this being a race condition that only manifests in rare circumstances, it's very difficult to create a reliable reproduction case. The issue mentioned above contains ThreadSanitizer logs that demonstrate this issue. TSan no longer complains with this patch applied, and we've not seen any additional issues from it after deploying it in production over the past week.

@meta-cla

meta-cla Bot commented Jul 16, 2025

Copy link
Copy Markdown

Hi @OrfeasZ!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 16, 2025
@meta-cla

meta-cla Bot commented Jul 16, 2025

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Jul 16, 2025
Some third-party libraries, like react-native-reanimated, can clone nodes
in a different thread while react-native is calling setNativeProps_DEPRECATED.
This results in a race condition, where a stale pointer to nativeProps_DEPRECATED
can be accessed, resulting in a crash.
@OrfeasZ OrfeasZ force-pushed the fix/clone-prop-update-race-condition branch from 67241d7 to b350148 Compare September 2, 2025 00:36
@renyufei8023

Copy link
Copy Markdown

rn0.81.1 still has this issue, when will we merge it?

@bartlomiejbloniarz

Copy link
Copy Markdown
Contributor

@cipolleschi Hi! Could we have someone look at this? I think it could also be a problem for c++ animated.

@ismaelsousa

ismaelsousa commented Sep 20, 2025

Copy link
Copy Markdown

Hello, have any of you had any problems with the patch so far?

[Edited - 22 Sep]
I will release it today for my users

@ismaelsousa

ismaelsousa commented Sep 24, 2025

Copy link
Copy Markdown

I patched locally and released it to my users so far, so great, no more crashes 🎉
Someone from meta really needs to look at this. I was having a 23% crash rate in the users' sections

* architecture and will be removed in the future.
*/
mutable std::unique_ptr<folly::dynamic> nativeProps_DEPRECATED;
mutable std::recursive_mutex nativePropsMutex;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this needs to be a recursive mutex instead of a plain one?

Does this need to be ShadowNodeFamily scoped, or would a single global mutex on UIManager be sufficient?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about the internals of react native, so took the safe approach of using a recursive one to prevent deadlocks in the case the critical path ends up trying to acquire the lock again recursively. That said, if that can't happen, it could be replaced with a regular mutex.

As for scoping, I'm not sure (again due to lack of internals knowledge). The main issue this tries to address is concurrent writes / reads to the nativeProps_DEPRECATED field, which is why I added it there, trying to keep the locking exactly to where it's needed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick with a normal mutex here - I don't see any way this could be re-entrant.

@OrfeasZ

OrfeasZ commented Feb 3, 2026

Copy link
Copy Markdown
Author

@javache Could we get an update on this? Is there anything I should change so we can get this merged?

@michael-tugby

Copy link
Copy Markdown

@javache Could we get an update on this? We need this fix for our project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants