[Sandbox Broker] Synchronize storage access

Synchronize storage access to main thread only, to prevent enumeration
from hitting a case of the main thread writing to the storage.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
swiftingly
Christopher Snowhill 2022-06-23 23:35:26 -07:00
parent be6453e048
commit f3f3d436ba
1 changed files with 41 additions and 24 deletions

View File

@ -142,6 +142,14 @@ static SandboxBroker *kSharedSandboxBroker = nil;
return YES; 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 { - (SandboxEntry *)recursivePathTest:(NSURL *)url {
for(SandboxEntry *entry in storage) { for(SandboxEntry *entry in storage) {
if(entry.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:entry.path]]) { if(entry.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:entry.path]]) {
@ -150,6 +158,9 @@ static SandboxBroker *kSharedSandboxBroker = nil;
} }
} }
__block 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];
@ -165,23 +176,29 @@ static SandboxBroker *kSharedSandboxBroker = nil;
if(token.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:token.path]]) { if(token.path && [SandboxBroker isPath:url aSubdirectoryOf:[NSURL fileURLWithPath:token.path]]) {
SandboxEntry *entry = [[SandboxEntry alloc] initWithToken:token]; SandboxEntry *entry = [[SandboxEntry alloc] initWithToken:token];
ret = entry;
return;
}
}
}
});
if(ret) {
BOOL isStale; BOOL isStale;
NSError *err = nil; NSError *err = nil;
NSURL *secureUrl = [NSURL URLByResolvingBookmarkData:token.bookmark options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:&isStale error:&err]; NSURL *secureUrl = [NSURL URLByResolvingBookmarkData:ret.token.bookmark options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:&isStale error:&err];
if(!secureUrl && err) { if(!secureUrl && err) {
ALog(@"Failed to access bookmark for URL: %@, error: %@", token.path, [err localizedDescription]); ALog(@"Failed to access bookmark for URL: %@, error: %@", ret.token.path, [err localizedDescription]);
return nil; return nil;
} }
entry.secureUrl = secureUrl; ret.secureUrl = secureUrl;
[storage addObject:entry]; [storage addObject:ret];
[secureUrl startAccessingSecurityScopedResource]; [secureUrl startAccessingSecurityScopedResource];
return entry; return ret;
}
}
} }
return nil; return nil;