From a44ab2957c6994fa44bd9644ab10da142109bab8 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 3 Jun 2019 16:11:20 -0700 Subject: [PATCH] Protect access to RCTTurboModuleCache Summary: The `_rctTurboModuleCache` `std::unordered_map` can be accessed by multiple threads at the same time via the `provideRCTTurboModule` method. Since `provideRCTTurboModule` both reads and writes to `_rctTurboModuleCache`, this is really bad because we could end up reading from `_rctTurboModuleCache` while it's in an invalid state. Therefore, in this diff, I'm making it so that only one thread at a time can enter `provideRCTTurboModule`. Reviewed By: fkgozali Differential Revision: D15609987 fbshipit-source-id: e24e1f5cc2351d8cbb820b7a97074aacd06eec9d --- .../core/platform/ios/RCTTurboModuleManager.mm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm index 0da68b3f3db64e..93f91f00ef7769 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm @@ -8,6 +8,7 @@ #import "RCTTurboModuleManager.h" #import +#import #import #import @@ -45,6 +46,18 @@ @implementation RCTTurboModuleManager { */ std::unordered_map> _rctTurboModuleCache; std::unordered_map> _turboModuleCache; + + /** + * _rctTurboModuleCache can be accessed by muitiple threads at once via + * the provideRCTTurboModule method. This can lead to races. Therefore, we + * need to protect access to this unordered_map. + * + * Note: + * There's no need to protect access to _turboModuleCache because that cache + * is only accessed within provideTurboModule, which is only invoked by the + * JS thread. + */ + std::mutex _rctTurboModuleCacheLock; } - (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id)delegate @@ -198,6 +211,8 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name */ - (id)provideRCTTurboModule:(const char *)moduleName { + std::lock_guard guard{_rctTurboModuleCacheLock}; + auto rctTurboModuleCacheLookup = _rctTurboModuleCache.find(moduleName); if (rctTurboModuleCacheLookup != _rctTurboModuleCache.end()) { return rctTurboModuleCacheLookup->second;