]> git.saurik.com Git - apple/security.git/blob - experiment/tool/experimentTool.m
Security-59754.41.1.tar.gz
[apple/security.git] / experiment / tool / experimentTool.m
1 //
2 // experimentTool.m
3 // experimentTool
4 //
5
6 #import <Foundation/Foundation.h>
7 #import <Security/SecExperimentPriv.h>
8 #import <Security/SecTrustPriv.h>
9 #import <CoreFoundation/CFXPCBridge.h>
10 #import <xpc/xpc.h>
11
12 static NSString *kExperimentRunResultKeySkips = @"Skips";
13 static NSString *kExperimentRunResultKeyConfigurations = @"Configurations";
14 static NSString *kExperimentRunResultKeyRuns = @"Runs";
15
16 static NSDictionary<NSString *, NSObject *> *
17 run_experiment(const char *experiment_name, size_t num_runs, bool sampling_disabled)
18 {
19 __block size_t runs = 0;
20 __block size_t skips = 0;
21 __block NSMutableArray<NSDictionary *> *configurations = [[NSMutableArray<NSDictionary *> alloc] init];
22 for (size_t i = 0; i < num_runs; i++) {
23 (void)sec_experiment_run_with_sampling_disabled(experiment_name, ^bool(const char *identifier, xpc_object_t experiment_config) {
24 runs++;
25 NSDictionary* configuration = (__bridge_transfer NSDictionary*)_CFXPCCreateCFObjectFromXPCObject(experiment_config);
26 if (configuration != NULL) {
27 [configurations addObject:configuration];
28 }
29 return true;
30 }, ^(const char * _Nonnull identifier) {
31 skips++;
32 }, sampling_disabled);
33 }
34
35 return @{kExperimentRunResultKeyRuns: @(runs),
36 kExperimentRunResultKeySkips: @(skips),
37 kExperimentRunResultKeyConfigurations: configurations,
38 };
39 }
40
41 static void
42 usage(const char *argv[])
43 {
44 fprintf(stderr, "Usage: %s [-h] [-s] [-e <experiment>] [-n <number of runs>]\n", argv[0]);
45 }
46
47 int
48 main(int argc, const char *argv[])
49 {
50 BOOL showUsage = NO;
51 int arg = 0;
52 char * const *gargv = (char * const *)argv;
53 char *experiment_name = NULL;
54 size_t num_runs = 0;
55 bool sampling_disabled = true;
56 bool update_asset = false;
57 bool read_asset = false;
58 while ((arg = getopt(argc, gargv, "e:n:sruh")) != -1) {
59 switch (arg) {
60 case 'e':
61 free(experiment_name); // Only the last instance of -e counts
62 experiment_name = strdup(optarg);
63 break;
64 case 'n':
65 num_runs = (size_t)atoi(optarg);
66 break;
67 case 's':
68 sampling_disabled = false;
69 break;
70 case 'r':
71 read_asset = true;
72 break;
73 case 'u':
74 update_asset = true;
75 break;
76 case 'h':
77 showUsage = YES;
78 break;
79 default:
80 fprintf(stderr, "%s: FAILURE: unknown option \"%c\"\n", argv[0], arg);
81 free(experiment_name);
82 return -1;
83 }
84 }
85
86 if (optind != argc) {
87 fprintf(stderr, "%s: FAILURE: argument missing parameter \"%c\"\n", argv[0], arg);
88 free(experiment_name);
89 return -2;
90 }
91
92 if (showUsage) {
93 usage(argv);
94 free(experiment_name);
95 return EXIT_SUCCESS;
96 }
97
98 uint64_t version = 0;
99 if (update_asset) {
100 CFErrorRef update_error = NULL;
101 version = SecTrustOTASecExperimentGetUpdatedAsset(&update_error);
102 if (update_error != NULL) {
103 NSLog(@"Failed to fetch latest asset: %@", (__bridge NSError *)update_error);
104 free(experiment_name);
105 return -3;
106 } else {
107 NSLog(@"Fetched asset version: %zu", (size_t)version);
108 }
109 }
110
111 if (read_asset) {
112 CFErrorRef copy_error = NULL;
113 NSDictionary *asset = CFBridgingRelease(SecTrustOTASecExperimentCopyAsset(&copy_error));
114 if (copy_error != NULL) {
115 NSLog(@"Failed to copy asset: %@", copy_error);
116 free(experiment_name);
117 return -4;
118 } else {
119 NSLog(@"Copied asset: %@", asset);
120 }
121 }
122
123 if (num_runs > 0) {
124 NSLog(@"Running %zu experiments with asset verison %llu", num_runs, version);
125 NSDictionary<NSString *, NSObject *> *results = run_experiment(experiment_name, num_runs, sampling_disabled);
126 [results enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSObject * _Nonnull obj, BOOL * _Nonnull stop) {
127 NSLog(@"Experiment %@: %@", key, obj);
128 }];
129 } else {
130 NSLog(@"Not running experiment.");
131 }
132
133 free(experiment_name);
134 return EXIT_SUCCESS;
135 }