Repository navigation
Commit 42b1e31
Fix use-after-free race in RCTInstance callFunctionOnJSModule
Summary:
WARNING: Generated by Autopilot (alpha) — review carefully, verify the underlying claim before accepting.
Agent: Bugs Agent | Trajectory: https://www.internalfb.com/intern/devai/devmate/inspector/4b82dbca-6e63-49ae-828e-b8401b428572/ | SC job: https://www.internalfb.com/intern/sandcastle/instance/4503602613718376/
---
Twilight iOS build 391 crashes with `EXC_BAD_ACCESS` / `KERN_INVALID_ADDRESS at 0x30` in `BufferedRuntimeExecutor::execute`, from `-[RCTSettingsManager userDefaultsDidChange:]` -> `-[RCTInstance callFunctionOnJSModule:method:args:]` -> `ReactInstance::callFunctionOnModule`, on a background `FBAppJobs` queue during cold start.
`callFunctionOnJSModule` is called from arbitrary threads (here, an off-main NSUserDefaults write by the code-usage app job). It checked `_valid` and then dereferenced `_reactInstance` with nothing stopping `-invalidate` from tearing down the `ReactInstance` in between. Before 7c6ccb595d69, the `bufferedRuntimeExecutor_ == nullptr` early return in `ReactInstance::callFunctionOnModule` happened to hide this, because freed memory read back as zero. Removing that check turned the latent use-after-free into a crash.
The fix takes `_invalidationMutex`, the lock `-_loadScriptFromSource` already uses for this purpose and that `-invalidate` holds while setting `_valid = false`. The check and the dereference now happen together relative to teardown. The `folly::dynamic` conversion stays outside the lock because the `settingsUpdated` payload is the whole NSUserDefaults dictionary. `callFunctionOnModule` only enqueues work on the runtime executor and never runs JS inline, so holding the lock adds no re-entrancy or deadlock risk.
Not restoring the removed null check is deliberate: it relies on allocator behavior and only masks the use-after-free. Other methods in this file (`registerSegmentWithId:`, `_handleMemoryWarning`, the `getBufferedRuntimeExecutor()` sites) and the macOS copy have the same unguarded pattern and are left for follow-up.
Differential Revision: D1228315701 parent 7c007b3 commit 42b1e31
1 file changed
Lines changed: 12 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
174 | | - | |
175 | | - | |
176 | | - | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
177 | 185 | | |
| 186 | + | |
178 | 187 | | |
179 | 188 | | |
180 | 189 | | |
| |||
0 commit comments