From 431849414fa0df86196df5b7ec86bbec378139f2 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Fri, 24 Jun 2022 14:58:56 -0700 Subject: [PATCH] [Sandbox Broker] Fix deadlock and crash The crash was because we weren't copying the results array before iterating over it, and the deadlock was because this was forced to go through the main thread, rather than going through its calling thread, which could lock up if the main thread was busy working with the Sandbox Broker object. Signed-off-by: Christopher Snowhill --- Utils/SandboxBroker.m | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/Utils/SandboxBroker.m b/Utils/SandboxBroker.m index afdfce34a..e63696f80 100644 --- a/Utils/SandboxBroker.m +++ b/Utils/SandboxBroker.m @@ -142,40 +142,30 @@ static SandboxBroker *kSharedSandboxBroker = nil; return YES; } -static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_block_t block) { - if(dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) { - block(); - } else { - dispatch_sync(queue, block); - } -} - - (SandboxEntry *)recursivePathTest:(NSURL *)url { - __block SandboxEntry *ret = nil; + SandboxEntry *ret = nil; - dispatch_sync_reentrant(dispatch_get_main_queue(), ^{ - NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer]; + NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer]; - NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:NO]; + NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:NO]; - NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"]; - request.sortDescriptors = @[sortDescriptor]; + NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"]; + request.sortDescriptors = @[sortDescriptor]; - NSError *error = nil; - NSArray *results = [pc.viewContext executeFetchRequest:request error:&error]; - if(results) results = [results copy]; + NSError *error = nil; + NSArray *results = [pc.viewContext executeFetchRequest:request error:&error]; + if(results) results = [results copy]; - if(results && [results count] > 0) { - for(SandboxToken *token in results) { - if(token.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:token.path]]) { - SandboxEntry *entry = [[SandboxEntry alloc] initWithToken:token]; + if(results && [results count] > 0) { + for(SandboxToken *token in results) { + if(token.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:token.path]]) { + SandboxEntry *entry = [[SandboxEntry alloc] initWithToken:token]; - ret = entry; - return; - } + ret = entry; + break; } } - }); + } if(ret) { BOOL isStale;