From d8141384d241c6d2edda44bc5303733a1b1d69ce Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 4 Mar 2025 14:06:25 -0500 Subject: [PATCH] Ensure threadsafe access to mutable MTRDeviceController_XPC state. The node ID and compressed fabric ID can mutate in controllerConfigurationUpdated:, and that can race with the property getters; ensure we don't have a data race in that situation. --- .../Framework/CHIP/MTRDeviceController_XPC.mm | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm index 3000c06ef775f1..6d110ba73b903d 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm @@ -54,7 +54,10 @@ @interface MTRDeviceController_XPC () // #define MTR_HAVE_MACH_SERVICE_NAME_CONSTRUCTOR -@implementation MTRDeviceController_XPC +@implementation MTRDeviceController_XPC { + // Protects access to the data set in controllerConfigurationUpdated: + os_unfair_lock _configurationLock; +} #pragma mark - Node ID Management @@ -119,8 +122,20 @@ - (void)forgetDeviceWithNodeID:(NSNumber *)nodeID } #pragma mark - XPC + @synthesize controllerNodeID = _controllerNodeID; +- (nullable NSNumber *)controllerNodeID +{ + std::lock_guard lock(_configurationLock); + return _controllerNodeID; +} + @synthesize compressedFabricID = _compressedFabricID; +- (nullable NSNumber *)compressedFabricID +{ + std::lock_guard lock(_configurationLock); + return _compressedFabricID; +} + (NSMutableSet *)_allowedClasses { @@ -345,6 +360,7 @@ - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParamete self.uniqueIdentifier = UUID; self.xpcParameters = xpcParameters; _workQueue = dispatch_queue_create("MTRDeviceController_XPC_queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _configurationLock = OS_UNFAIR_LOCK_INIT; if (![self _setupXPCConnection]) { return nil; @@ -490,6 +506,8 @@ - (oneway void)controller:(NSUUID *)controller controllerConfigurationUpdated:(N NSDictionary * controllerContext = MTR_SAFE_CAST(configuration[MTRDeviceControllerRegistrationControllerContextKey], NSDictionary); if (controllerContext) { + std::lock_guard lock(_configurationLock); + NSNumber * controllerNodeID = MTR_SAFE_CAST(controllerContext[MTRDeviceControllerRegistrationControllerNodeIDKey], NSNumber); if (controllerNodeID) { _controllerNodeID = controllerNodeID;