Skip to content

Commit

Permalink
more concurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
jjolano committed Feb 21, 2023
1 parent 72454b0 commit 67e663b
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 30 deletions.
36 changes: 29 additions & 7 deletions Shadow.dylib/hooks/NSFileManager.x
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ static char* _NSDirectoryEnumerator_shdw_key = "shdw";

NSString* base = objc_getAssociatedObject(self, _NSDirectoryEnumerator_shdw_key);

if(!base) {
NSLog(@"NSDirectoryEnumerator base not found");
base = @"";
}

if([_shadow isPathRestricted:base]) {
return @[];
}
Expand Down Expand Up @@ -51,6 +56,11 @@ static char* _NSDirectoryEnumerator_shdw_key = "shdw";

NSString* base = objc_getAssociatedObject(self, _NSDirectoryEnumerator_shdw_key);

if(!base) {
NSLog(@"NSDirectoryEnumerator base not found");
base = @"";
}

if([_shadow isPathRestricted:base]) {
return nil;
}
Expand Down Expand Up @@ -210,7 +220,7 @@ static char* _NSDirectoryEnumerator_shdw_key = "shdw";
- (NSDirectoryEnumerator<NSURL *> *)enumeratorAtURL:(NSURL *)url includingPropertiesForKeys:(NSArray<NSURLResourceKey> *)keys options:(NSDirectoryEnumerationOptions)mask errorHandler:(BOOL (^)(NSURL *url, NSError *error))handler {
NSDirectoryEnumerator* result = %orig;

if(!isCallerTweak() && result) {
if(result) {
objc_setAssociatedObject(result, _NSDirectoryEnumerator_shdw_key, [url path], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSLog(@"%@: %@", @"enumeratorAtURL", url);
}
Expand All @@ -221,7 +231,7 @@ static char* _NSDirectoryEnumerator_shdw_key = "shdw";
- (NSDirectoryEnumerator<NSString *> *)enumeratorAtPath:(NSString *)path {
NSDirectoryEnumerator* result = %orig;

if(!isCallerTweak() && result) {
if(result) {
objc_setAssociatedObject(result, _NSDirectoryEnumerator_shdw_key, path, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSLog(@"%@: %@", @"enumeratorAtPath", path);
}
Expand All @@ -248,12 +258,18 @@ static char* _NSDirectoryEnumerator_shdw_key = "shdw";

if(result) {
NSMutableArray* result_filtered = [result mutableCopy];
for(NSString* result_path in result) {

[result enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString* result_path, NSUInteger idx, BOOL* stop) {
if([_shadow isPathRestricted:result_path options:@{kShadowRestrictionWorkingDir : path}]) {
[result_filtered removeObject:result_path];
}
}
}];

// for(NSString* result_path in result) {
// if([_shadow isPathRestricted:result_path options:@{kShadowRestrictionWorkingDir : path}]) {
// [result_filtered removeObject:result_path];
// }
// }

result = [result_filtered copy];
}
Expand All @@ -277,11 +293,17 @@ static char* _NSDirectoryEnumerator_shdw_key = "shdw";
if(result) {
NSMutableArray* result_filtered = [result mutableCopy];

for(NSString* result_path in result) {
[result enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString* result_path, NSUInteger idx, BOOL* stop) {
if([_shadow isPathRestricted:result_path options:@{kShadowRestrictionWorkingDir : path}]) {
[result_filtered removeObject:result_path];
}
}
}];

// for(NSString* result_path in result) {
// if([_shadow isPathRestricted:result_path options:@{kShadowRestrictionWorkingDir : path}]) {
// [result_filtered removeObject:result_path];
// }
// }

result = [result_filtered copy];
}
Expand Down
97 changes: 74 additions & 23 deletions Shadow.framework/ShadowService.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,67 @@ @implementation ShadowService {
}

- (void)addRuleset:(NSDictionary *)ruleset {
NSOperationQueue* queue = [NSOperationQueue new];
[queue setQualityOfService:NSOperationQualityOfServiceUserInteractive];

// Preprocess ruleset
NSMutableDictionary* ruleset_processed = [ruleset mutableCopy];

NSArray* wpred = [ruleset objectForKey:@"WhitelistPredicates"];
[queue addOperationWithBlock:^{
NSArray* burlschemes = [ruleset objectForKey:@"BlacklistURLSchemes"];

if([burlschemes count]) {
[ruleset_processed setObject:[NSSet setWithArray:burlschemes] forKey:@"BlacklistURLSchemes"];
}
}];

if([wpred count]) {
NSMutableArray* wpred_new = [NSMutableArray new];
[queue addOperationWithBlock:^{
NSArray* wexact = [ruleset objectForKey:@"WhitelistExactPaths"];

for(NSString* pred_str in wpred) {
[wpred_new addObject:[NSPredicate predicateWithFormat:pred_str]];
if([wexact count]) {
[ruleset_processed setObject:[NSSet setWithArray:wexact] forKey:@"WhitelistExactPaths"];
}
}];

NSPredicate* wpred_compound = [NSCompoundPredicate orPredicateWithSubpredicates:wpred_new];
[ruleset_processed setObject:wpred_compound forKey:@"WhitelistPredicates"];
}
[queue addOperationWithBlock:^{
NSArray* bexact = [ruleset objectForKey:@"BlacklistExactPaths"];

NSArray* bpred = [ruleset objectForKey:@"BlacklistPredicates"];
if([bexact count]) {
[ruleset_processed setObject:[NSSet setWithArray:bexact] forKey:@"BlacklistExactPaths"];
}
}];

if([bpred count]) {
NSMutableArray* bpred_new = [NSMutableArray new];
[queue addOperationWithBlock:^{
NSArray* wpred = [ruleset objectForKey:@"WhitelistPredicates"];

for(NSString* pred_str in bpred) {
[bpred_new addObject:[NSPredicate predicateWithFormat:pred_str]];
};
if([wpred count]) {
NSMutableArray* wpred_new = [NSMutableArray new];

NSPredicate* bpred_compound = [NSCompoundPredicate orPredicateWithSubpredicates:bpred_new];
[ruleset_processed setObject:bpred_compound forKey:@"BlacklistPredicates"];
}
for(NSString* pred_str in wpred) {
[wpred_new addObject:[NSPredicate predicateWithFormat:pred_str]];
}

NSPredicate* wpred_compound = [NSCompoundPredicate orPredicateWithSubpredicates:wpred_new];
[ruleset_processed setObject:wpred_compound forKey:@"WhitelistPredicates"];
}
}];

[queue addOperationWithBlock:^{
NSArray* bpred = [ruleset objectForKey:@"BlacklistPredicates"];

if([bpred count]) {
NSMutableArray* bpred_new = [NSMutableArray new];

for(NSString* pred_str in bpred) {
[bpred_new addObject:[NSPredicate predicateWithFormat:pred_str]];
};

NSPredicate* bpred_compound = [NSCompoundPredicate orPredicateWithSubpredicates:bpred_new];
[ruleset_processed setObject:bpred_compound forKey:@"BlacklistPredicates"];
}
}];

[queue waitUntilAllOperationsAreFinished];

// Add processed ruleset to our class
rulesets = [rulesets arrayByAddingObject:[ruleset_processed copy]];
Expand All @@ -67,12 +100,12 @@ - (NSDictionary *)handleMessageNamed:(NSString *)name withUserInfo:(NSDictionary
__block BOOL compliant = YES;

if(path && [path isAbsolutePath]) {
for(NSDictionary* ruleset in rulesets) {
[rulesets enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSDictionary* ruleset, NSUInteger idx, BOOL* stop) {
if(![[self class] isPathCompliant:path withRuleset:ruleset]) {
compliant = NO;
break;
*stop = YES;
}
}
}];
}

response = @{
Expand Down Expand Up @@ -144,14 +177,14 @@ - (NSDictionary *)handleMessageNamed:(NSString *)name withUserInfo:(NSDictionary

if(scheme) {
// Check rulesets
for(NSDictionary* ruleset in rulesets) {
[rulesets enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSDictionary* ruleset, NSUInteger idx, BOOL* stop) {
NSSet* bschemes = [ruleset objectForKey:@"BlacklistURLSchemes"];

if([bschemes containsObject:scheme]) {
restricted = YES;
break;
*stop = YES;
}
}
}];
}

response = @{
Expand Down Expand Up @@ -186,6 +219,24 @@ - (void)loadRulesets {
// load rulesets
NSArray* ruleset_urls = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:ROOT_PATH_NS(@SHADOW_RULESETS) isDirectory:YES] includingPropertiesForKeys:@[] options:0 error:nil];

// [ruleset_urls enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSURL* url, NSUInteger idx, BOOL* stop) {
// NSDictionary* ruleset = [NSDictionary dictionaryWithContentsOfURL:url];

// if(ruleset) {
// [self addRuleset:ruleset];

// NSDictionary* info = [ruleset objectForKey:@"RulesetInfo"];

// if(info) {
// NSLog(@"loaded ruleset '%@' by %@", [info objectForKey:@"Name"], [info objectForKey:@"Author"]);
// } else {
// NSLog(@"loaded ruleset %@", [[url path] lastPathComponent]);
// }
// } else {
// NSLog(@"failed to load ruleset at url %@", url);
// }
// }];

if(ruleset_urls) {
for(NSURL* url in ruleset_urls) {
NSDictionary* ruleset = [NSDictionary dictionaryWithContentsOfURL:url];
Expand Down

0 comments on commit 67e663b

Please sign in to comment.