From dd766ac479947e6985f53d48ddab54c4a7ae8728 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 28 Jul 2023 20:53:57 -0400 Subject: [PATCH] Fix missing lock around _controllers access. (#28384) The rules for the locking are that we must lock when on the Matter queue, which is the case in createControllerOnExistingFabric. --- src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 27e15ebd700d23..f26492b9a99448 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -96,7 +96,7 @@ @interface MTRDeviceControllerFactory () // // 1) The only mutating accesses to the controllers array happen when the // current queue is not the Matter queue. This is a good assumption, because -// the implementation of the fucntions that mutate the array do sync dispatch +// the implementation of the functions that mutate the array do sync dispatch // to the Matter queue, which would deadlock if they were called when that // queue was the current queue. // 2) It's our API consumer's responsibility to serialize access to us from @@ -597,7 +597,11 @@ - (MTRDeviceController * _Nullable)createControllerOnExistingFabric:(MTRDeviceCo return; } - for (MTRDeviceController * existing in _controllers) { + os_unfair_lock_lock(&_controllersLock); + NSArray * controllersCopy = [_controllers copy]; + os_unfair_lock_unlock(&_controllersLock); + + for (MTRDeviceController * existing in controllersCopy) { BOOL isRunning = YES; // assume the worst if ([existing isRunningOnFabric:fabricTable fabricIndex:fabric->GetFabricIndex() isRunning:&isRunning] != CHIP_NO_ERROR) {