-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Fix potential race conditions when executing commitHooks #53862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
cc03e41
to
42ab383
Compare
) Summary: Recently we saw `use-after-free race condition` where the ImageFetcher object was being destroyed while still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause could be improper lifecycle management between ImageFetcher destruction and commit hook execution. The fix here modifies `UIManager::shadowTreeWillCommit()` to create a stable snapshot by copying the commitHooks_ vector while holding the lock. ## Reason - If a thread is iterating over `commitHooks_` with a `shared_lock`, and another thread acquires a `unique_lock` to modify the vector (add/remove), the iterator in the first thread can become invalid, leading to a crash (use-after-free or out-of-bounds). - This can happen if the lock is not held for the entire duration of the read or write, or if the lock is not correctly used everywhere commitHooks_ is accessed. Changelog: [Internal] Differential Revision: D82846245
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
) Summary: Recently we saw `use-after-free race condition` where the ImageFetcher object was being destroyed while still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause could be improper lifecycle management between ImageFetcher destruction and commit hook execution. The fix here modifies `UIManager::shadowTreeWillCommit()` to create a stable snapshot by copying the commitHooks_ vector while holding the lock. ## Reason - If a thread is iterating over `commitHooks_` with a `shared_lock`, and another thread acquires a `unique_lock` to modify the vector (add/remove), the iterator in the first thread can become invalid, leading to a crash (use-after-free or out-of-bounds). - This can happen if the lock is not held for the entire duration of the read or write, or if the lock is not correctly used everywhere commitHooks_ is accessed. Changelog: [Internal] Differential Revision: D82846245
42ab383
to
160497a
Compare
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
) Summary: Recently we saw `use-after-free race condition` where the ImageFetcher object was being destroyed while still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause could be improper lifecycle management between ImageFetcher destruction and commit hook execution. The fix here modifies `UIManager::shadowTreeWillCommit()` to create a stable snapshot by copying the commitHooks_ vector while holding the lock. ## Reason - If a thread is iterating over `commitHooks_` with a `shared_lock`, and another thread acquires a `unique_lock` to modify the vector (add/remove), the iterator in the first thread can become invalid, leading to a crash (use-after-free or out-of-bounds). - This can happen if the lock is not held for the entire duration of the read or write, or if the lock is not correctly used everywhere commitHooks_ is accessed. Changelog: [Internal] Differential Revision: D82846245
) Summary: Recently we saw `use-after-free race condition` where the ImageFetcher object was being destroyed while still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause could be improper lifecycle management between ImageFetcher destruction and commit hook execution. The fix here modifies `UIManager::shadowTreeWillCommit()` to create a stable snapshot by copying the commitHooks_ vector while holding the lock. ## Reason - If a thread is iterating over `commitHooks_` with a `shared_lock`, and another thread acquires a `unique_lock` to modify the vector (add/remove), the iterator in the first thread can become invalid, leading to a crash (use-after-free or out-of-bounds). - This can happen if the lock is not held for the entire duration of the read or write, or if the lock is not correctly used everywhere commitHooks_ is accessed. Changelog: [Internal] Differential Revision: D82846245
160497a
to
d200c2e
Compare
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
) Summary: Recently we saw `use-after-free race condition` where the ImageFetcher object was being destroyed while still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause could be improper lifecycle management between ImageFetcher destruction and commit hook execution. The fix here modifies `UIManager::shadowTreeWillCommit()` to create a stable snapshot by copying the commitHooks_ vector while holding the lock. ## Reason - If a thread is iterating over `commitHooks_` with a `shared_lock`, and another thread acquires a `unique_lock` to modify the vector (add/remove), the iterator in the first thread can become invalid, leading to a crash (use-after-free or out-of-bounds). - This can happen if the lock is not held for the entire duration of the read or write, or if the lock is not correctly used everywhere commitHooks_ is accessed. Changelog: [Internal] Differential Revision: D82846245
d200c2e
to
ab61f78
Compare
…mitHooks (facebook#53862) Summary: Recently, we observed a `use-after-free race condition` where the ImageFetcher object was destroyed while it was still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause appears to be improper lifecycle management between ImageFetcher destruction and commit hook execution. The issue seems to be that `UIManagerCommitHook*` are raw pointers. If we register or unregister them off the JS thread, we will encounter issues with the lifecycle management of the commit hooks. Therefore, it is advisable to revert parts of this change: [https://github.com/facebook/react-native/pull/53491/files](https://github.com/facebook/react-native/pull/53491/files) and remove `UIManagerCommitHookManager`. Alternatively, we can register or unregister the CommitHook by scheduling a task on the RuntimeScheduler and accessing the UIManagerBinding. Changelog: [Internal] Differential Revision: D82846245
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
…mitHooks (facebook#53862) Summary: Recently, we observed a `use-after-free race condition` where the ImageFetcher object was destroyed while it was still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause appears to be improper lifecycle management between ImageFetcher destruction and commit hook execution. The issue seems to be that `UIManagerCommitHook*` are raw pointers. If we register or unregister them off the JS thread, we will encounter issues with the lifecycle management of the commit hooks. Therefore, it is advisable to revert parts of this change: [https://github.com/facebook/react-native/pull/53491/files](https://github.com/facebook/react-native/pull/53491/files) and remove `UIManagerCommitHookManager`. Alternatively, we can register or unregister the CommitHook by scheduling a task on the RuntimeScheduler and accessing the UIManagerBinding. Changelog: [Internal] Differential Revision: D82846245
ab61f78
to
b38b4de
Compare
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
b38b4de
to
7ff03a1
Compare
…mitHooks (facebook#53862) Summary: Recently, we observed a `use-after-free race condition` where the ImageFetcher object was destroyed while it was still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause appears to be improper lifecycle management between ImageFetcher destruction and commit hook execution. The issue seems to be that `UIManagerCommitHook*` are raw pointers. If we register or unregister them off the JS thread, we will encounter issues with the lifecycle management of the commit hooks. Therefore, it is advisable to revert parts of this change: [https://github.com/facebook/react-native/pull/53491/files](https://github.com/facebook/react-native/pull/53491/files) and remove `UIManagerCommitHookManager`. Alternatively, we can register or unregister the CommitHook by scheduling a task on the RuntimeScheduler and accessing the UIManagerBinding. Changelog: [Internal] Differential Revision: D82846245
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
…mitHooks (facebook#53862) Summary: Recently, we observed a `use-after-free race condition` where the ImageFetcher object was destroyed while it was still registered as a UIManagerCommitHook. The crash occurred in `std::vector::size()` at line 635 when accessing corrupted memory. The root cause appears to be improper lifecycle management between ImageFetcher destruction and commit hook execution. The issue seems to be that `UIManagerCommitHook*` are raw pointers. If we register or unregister them off the JS thread, we will encounter issues with the lifecycle management of the commit hooks. Therefore, it is advisable to revert parts of this change: [https://github.com/facebook/react-native/pull/53491/files](https://github.com/facebook/react-native/pull/53491/files) and remove `UIManagerCommitHookManager`. Alternatively, we can register or unregister the CommitHook by scheduling a task on the RuntimeScheduler and accessing the UIManagerBinding. Changelog: [Internal] Differential Revision: D82846245
7ff03a1
to
e3f1dbb
Compare
@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating diff in D82846245. |
Summary:
Recently we saw use-after-free race condition where the ImageFetcher object was being destroyed while still registered as a UIManagerCommitHook.
The crash occurred in std::vector::size() at line 635 when accessing corrupted memory.
The root cause could be improper lifecycle management between ImageFetcher destruction and commit hook execution.
The fix here modifies UIManager::shadowTreeWillCommit() to create a stable snapshot by copying the commitHooks_ vector while holding the lock.
Changelog: [Internal]
Differential Revision: D82846245