]> git.saurik.com Git - apple/security.git/blob - RegressionTests/secsecstaticcodeapitest.c
Security-59754.60.13.tar.gz
[apple/security.git] / RegressionTests / secsecstaticcodeapitest.c
1 //
2 // secsecstaticcodeapitest.c
3 // secsecstaticcodeapitest
4 //
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <AssertMacros.h>
11 #include <sys/xattr.h>
12 #include <Security/SecCodePriv.h>
13 #include <Security/SecCode.h>
14 #include <Security/SecStaticCode.h>
15
16 #define BEGIN() \
17 ({ \
18 fprintf(stdout, "[BEGIN] %s\n", __FUNCTION__); \
19 })
20
21 #define INFO(fmt, ...) \
22 ({ \
23 fprintf(stdout, fmt "\n", ##__VA_ARGS__); \
24 })
25
26 #define PASS(fmt, ...) \
27 ({ \
28 fprintf(stdout, "[PASS] %s " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
29 })
30
31 #define FAIL(fmt, ...) \
32 ({ \
33 fprintf(stdout, "[FAIL] %s " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
34 })
35
36 #define SAFE_RELEASE(x) \
37 ({ \
38 if (x) { \
39 CFRelease(x); \
40 x = NULL; \
41 } \
42 })
43
44 #define kCommandRedirectOutputToDevNULL " >/dev/null 2>&1"
45 #define BUILD_COMMAND(x) x kCommandRedirectOutputToDevNULL
46
47 #define kFAT32DiskImageFileDirectory "/tmp"
48 #define kFAT32DiskImageFileName "Security_SecStaticCodeAPITest.dmg"
49 #define kFAT32DiskImageFilePath kFAT32DiskImageFileDirectory "/" kFAT32DiskImageFileName
50
51 #define kFAT32DiskImageVolumeDirectory "/Volumes"
52 #define kFAT32DiskImageVolumeName "SEC_TEST"
53 #define kFAT32DiskImageVolumePath kFAT32DiskImageVolumeDirectory "/" kFAT32DiskImageVolumeName
54
55 #define kApplicationsPath "/Applications"
56 #define kSafariBundleName "Safari.app"
57 #define kSafariBundleOnSystemPath kApplicationsPath "/" kSafariBundleName
58 #define kSafariBundleOnVolumePath kFAT32DiskImageVolumePath "/" kSafariBundleName
59
60 static void
61 _cleanUpFAT32DiskImage(void)
62 {
63 // Delete disk image.
64 const char *command = BUILD_COMMAND("rm -rf " kFAT32DiskImageFilePath);
65 system(command);
66
67 // Detach volume.
68 command = BUILD_COMMAND("hdiutil detach " kFAT32DiskImageVolumePath);
69 system(command);
70 }
71
72 static int
73 _createFAT32DiskImage(void)
74 {
75 const char *command = BUILD_COMMAND("hdiutil create -fs FAT32 -size 256m -volname " kFAT32DiskImageVolumeName " " kFAT32DiskImageFilePath);
76 return system(command);
77 }
78
79 static int
80 _attachFAT32DiskImage(void)
81 {
82 const char *command = BUILD_COMMAND("hdiutil attach " kFAT32DiskImageFilePath);
83 return system(command);
84 }
85
86 static int
87 _copySafariBundleToVolume(void)
88 {
89 const char *command = BUILD_COMMAND("cp -R " kSafariBundleOnSystemPath " " kSafariBundleOnVolumePath);
90 return system(command);
91 }
92
93 static int
94 _confirmValidationPolicy(const char *path)
95 {
96 int ret = -1;
97 SecStaticCodeRef codeRef = NULL;
98 SecCSFlags createFlags = kSecCSDefaultFlags;
99 SecCSFlags validateFlags = kSecCSDefaultFlags | kSecCSStrictValidateStructure;
100
101 CFStringRef stringRef = NULL;
102 CFURLRef pathRef = NULL;
103
104 require(path, done);
105
106 stringRef = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)path, strlen(path), kCFStringEncodingASCII, false);
107 require(stringRef, done);
108
109 pathRef = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, stringRef, kCFURLPOSIXPathStyle, false);
110 require(pathRef, done);
111
112 OSStatus status = SecStaticCodeCreateWithPath(pathRef, createFlags, &codeRef);
113 require_noerr(status, done);
114 require(codeRef, done);
115
116 // Validate binary without kSecCSSkipXattrFiles. Expectation is this should fail.
117 status = SecStaticCodeCheckValidity(codeRef, validateFlags, NULL);
118 if (!status) {
119 INFO("%s validated without kSecCSSkipXattrFiles flag", path);
120 goto done;
121 }
122 SAFE_RELEASE(codeRef);
123
124 // Create codeRef again to clear state.
125 status = SecStaticCodeCreateWithPath(pathRef, createFlags, &codeRef);
126 require_noerr(status, done);
127 require(codeRef, done);
128
129 // Validate binary with kSecCSSkipXattrFiles. Expectation is this should pass.
130 validateFlags |= kSecCSSkipXattrFiles;
131 status = SecStaticCodeCheckValidity(codeRef, validateFlags, NULL);
132 if (status) {
133 INFO("%s is not valid even with kSecCSSkipXattrFiles flag", path);
134 goto done;
135 }
136
137 // Complete.
138 ret = 0;
139
140 done:
141 SAFE_RELEASE(codeRef);
142 SAFE_RELEASE(stringRef);
143 SAFE_RELEASE(pathRef);
144 return ret;
145 }
146
147 static int
148 CheckCheckValidity_kSecCSSkipXattrFiles(void)
149 {
150 BEGIN();
151
152 int ret = -1;
153
154 // Create FAT32 disk image.
155 if (_createFAT32DiskImage()) {
156 FAIL("_createFAT32DiskImage error");
157 goto done;
158 }
159 INFO("Created " kFAT32DiskImageFilePath);
160
161 // Attach disk image to the system.
162 if (_attachFAT32DiskImage()) {
163 FAIL("_attachFAT32DiskImage error");
164 goto done;
165 }
166 INFO("Attached " kFAT32DiskImageFilePath " as " kFAT32DiskImageVolumePath);
167
168 // Copy Safari.app to the attached volume.
169 if (_copySafariBundleToVolume()) {
170 FAIL("_copySafariBundleToVolume error");
171 goto done;
172 }
173 INFO("Copied " kSafariBundleOnSystemPath " to " kSafariBundleOnVolumePath);
174
175 // Write "com.apple.dummy" xattr to Safari.
176 const char *xattrName = "com.apple.dummy";
177 const uint32_t xattrValue = 0;
178
179 const char *safariBinary = kSafariBundleOnVolumePath "/Contents/MacOS/Safari";
180 if (setxattr(safariBinary, xattrName, &xattrValue, sizeof(xattrValue), 0, 0)) {
181 FAIL("%s setxattr error: %d [%s]", safariBinary, errno, strerror(errno));
182 goto done;
183 }
184 INFO("Wrote xattr \'%s\' to %s", xattrName, safariBinary);
185
186 const char *safariCodeResources = kSafariBundleOnVolumePath "/Contents/_CodeSignature/CodeResources";
187 if (setxattr(safariCodeResources, xattrName, &xattrValue, sizeof(xattrValue), 0, 0)) {
188 FAIL("%s setxattr error: %d [%s]", safariCodeResources, errno, strerror(errno));
189 goto done;
190 }
191 INFO("Wrote xattr \'%s\' to %s", xattrName, safariCodeResources);
192
193 // Validate Safari.app with and without kSecCSSkipXattrFiles flag.
194 if (_confirmValidationPolicy(kSafariBundleOnVolumePath)) {
195 FAIL("%s _confirmValidationPolicy error", kSafariBundleOnVolumePath);
196 goto done;
197 }
198 INFO("Validation policy on %s confirmed", kSafariBundleOnVolumePath);
199
200 PASS("Completed validation policy check with kSecCSSkipXattrFiles");
201 ret = 0;
202
203 done:
204 _cleanUpFAT32DiskImage();
205 return ret;
206 }
207
208 int main(void)
209 {
210 fprintf(stdout, "[TEST] secsecstaticcodeapitest\n");
211
212 int i;
213 int (*testList[])(void) = {
214 CheckCheckValidity_kSecCSSkipXattrFiles
215 };
216 const int numberOfTests = sizeof(testList) / sizeof(*testList);
217 int testResults[numberOfTests] = {0};
218
219 for (i = 0; i < numberOfTests; i++) {
220 testResults[i] = testList[i]();
221 }
222
223 fprintf(stdout, "[SUMMARY]\n");
224 for (i = 0; i < numberOfTests; i++) {
225 fprintf(stdout, "%d. %s\n", i+1, testResults[i] == 0 ? "Passed" : "Failed");
226 }
227
228 return 0;
229 }