]> git.saurik.com Git - apple/security.git/blob - libsecurity_codesigning/dtrace/codesign-watch.d
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_codesigning / dtrace / codesign-watch.d
1 #!/usr/sbin/dtrace -q -s
2 /*
3 * Demonstration D script for watching Code Signing activity in the system
4 *
5 * As presented, this script will record and report all Code Signing activity
6 * in one process (argument=pid), or all processes (argument='*').
7 * You are encouraged to modify it as you will. (A good start is to comment out
8 * the print statements you don't like to see.)
9 */
10 typedef uint64_t DTHandle; /* generic API handle (NOT a pointer) */
11 typedef uint8_t Hash[20]; /* SHA-1 */
12
13 typedef struct { /* from implementation */
14 uint32_t cputype;
15 uint32_t cpusubtype;
16 off_t offset;
17 uint8_t fileOnly;
18 } DiskRepContext;
19
20
21 /*
22 * Local variables used for suitable casting (only)
23 */
24 self uint8_t *hash;
25
26
27 /*
28 * Startup (this may take a while)
29 */
30 :::BEGIN
31 {
32 printf("Ready...\n");
33 }
34
35
36 /*
37 * Finishing (add statistics tracers here)
38 */
39 :::END
40 {
41 }
42
43
44 /*
45 * Track kernel-related objects.
46 * Each process has their own, and they're usually created very early.
47 */
48 struct {
49 DTHandle rep; /* DiskRep */
50 DTHandle staticCode; /* static code */
51 DTHandle code; /* dynamic code */
52 } kernel[pid_t];
53
54
55 /*
56 * Track DiskRep objects.
57 * DiskReps are drivers for on-disk formats. Beyond their natural concerns,
58 * they also carry the path information for StaticCode objects.
59 */
60 typedef struct {
61 DTHandle me; /* own handle, if valid */
62 string path; /* canonical path */
63 string type; /* type string */
64 DiskRepContext ctx; /* construction context, if any */
65 DTHandle sub; /* sub-DiskRep if any */
66 } DiskRep;
67 DiskRep rep[DTHandle]; /* all the DiskReps we've seen */
68
69 self uint64_t ctx; /* passes construction context, NULL if none */
70
71 codesign$1:::diskrep-create-* /* preset none */
72 { self->ctx = 0; }
73
74 codesign$1:::diskrep-create-kernel
75 {
76 rep[arg0].me = kernel[pid].rep = arg0;
77 rep[arg0].path = "(kernel)";
78 rep[arg0].type = "kernel";
79 printf("%8u %s[%d]%s(%p,KERNEL)\n",
80 timestamp, execname, pid, probename, arg0);
81 }
82
83 codesign$1:::diskrep-create-macho
84 {
85 rep[arg0].me = arg0;
86 rep[arg0].path = copyinstr(arg1);
87 rep[arg0].type = "macho";
88 self->ctx = arg2;
89 printf("%8u %s[%d]%s(%p,%s)\n",
90 timestamp, execname, pid, probename, arg0, rep[arg0].path);
91 }
92
93 codesign$1:::diskrep-create-bundle-path
94 {
95 rep[arg0].me = arg0;
96 rep[arg0].path = copyinstr(arg1);
97 rep[arg0].type = "bundle";
98 self->ctx = arg2;
99 rep[arg0].sub = arg3;
100 printf("%8u %s[%d]%s(%p,%s,%p)\n",
101 timestamp, execname, pid, probename,
102 arg0, rep[arg0].path, rep[arg0].sub);
103 }
104
105 codesign$1:::diskrep-create-bundle-ref
106 {
107 rep[arg0].me = arg0;
108 rep[arg0].path = "(from ref)";
109 rep[arg0].type = "bundle";
110 self->ctx = arg2;
111 rep[arg0].sub = arg3;
112 printf("%8u %s[%d]%s(%p,%s,%p)\n",
113 timestamp, execname, pid, probename,
114 arg0, rep[arg0].path, rep[arg0].sub);
115 }
116
117 codesign$1:::diskrep-create-file
118 {
119 rep[arg0].me = arg0;
120 rep[arg0].path = copyinstr(arg1);
121 rep[arg0].type = "file";
122 printf("%8u %s[%d]%s(%p,%s)\n",
123 timestamp, execname, pid, probename, arg0, rep[arg0].path);
124 }
125
126 self DiskRepContext *ctxp;
127
128 codesign$1:::diskrep-create-*
129 / self->ctx /
130 {
131 self->ctxp = (DiskRepContext *)copyin(self->ctx, sizeof(DiskRepContext));
132 rep[arg0].ctx = *self->ctxp;
133 printf("%8u %s[%d] ...context: arch=(0x%x,0x%x) offset=0x%x file=%d\n",
134 timestamp, execname, pid,
135 self->ctxp->cputype, self->ctxp->cpusubtype,
136 self->ctxp->offset, self->ctxp->fileOnly);
137 }
138
139 codesign$1:::diskrep-destroy
140 {
141 printf("%8u %s[%d]%s(%p,%s)\n",
142 timestamp, execname, pid, probename, arg0, rep[arg0].path);
143 rep[arg0].me = 0;
144 }
145
146
147 /*
148 * Track Code Signing API objects
149 */
150 typedef struct {
151 DTHandle me;
152 DTHandle host;
153 DTHandle staticCode; /* lazily acquired */
154 uint8_t *hash; /* dynamic hash from identify() */
155 } Code;
156 Code code[DTHandle];
157
158 typedef struct {
159 DTHandle me;
160 DTHandle rep;
161 uint8_t *hash; /* static hash from ...::cdHash() */
162 } StaticCode;
163 StaticCode staticCode[DTHandle];
164
165
166 codesign$1:::static-create
167 / arg1 == kernel[pid].rep /
168 {
169 staticCode[arg0].me = kernel[pid].staticCode = arg0;
170 staticCode[arg0].rep = arg1;
171 printf("%8u %s[%d]%s(%p=KERNEL[%p])\n",
172 timestamp, execname, pid, probename, arg0, arg1);
173 }
174
175 codesign$1:::static-create
176 / arg1 != kernel[pid].rep /
177 {
178 staticCode[arg0].me = arg0;
179 staticCode[arg0].rep = arg1;
180 printf("%8u %s[%d]%s(%p,%s[%p])\n",
181 timestamp, execname, pid, probename, arg0, rep[arg1].path, arg1);
182 }
183
184 codesign$1:::dynamic-create
185 / arg1 == 0 /
186 {
187 code[arg0].me = kernel[pid].code = arg0;
188 printf("%8u %s[%d]%s(%p=KERNEL)\n",
189 timestamp, execname, pid, probename, arg0);
190 }
191
192 codesign$1:::dynamic-create
193 / arg1 == kernel[pid].code /
194 {
195 code[arg0].me = arg0;
196 printf("%8u %s[%d]%s(%p,<KERNEL>)\n",
197 timestamp, execname, pid, probename, arg0);
198 }
199
200 codesign$1:::dynamic-create
201 / arg1 != 0 && arg1 != kernel[pid].code /
202 {
203 code[arg0].me = arg0;
204 code[arg0].host = arg1;
205 printf("%8u %s[%d]%s(%p,%p)\n",
206 timestamp, execname, pid, probename, arg0, arg1);
207 }
208
209 security_debug$1:::sec-destroy
210 / code[arg0].me == arg0 /
211 {
212 code[arg0].me = 0;
213 printf("%8u %s[%d]destroy code(%p)\n",
214 timestamp, execname, pid, arg0);
215 }
216
217 security_debug$1:::sec-destroy
218 / staticCode[arg0].me == arg0 /
219 {
220 staticCode[arg0].me = 0;
221 printf("%8u %s[%d]destroy staticCode(%p)\n",
222 timestamp, execname, pid, arg0);
223 }
224
225
226 /*
227 * Identification operations
228 */
229 codesign$1:::guest-identify-*
230 {
231 printf("%8u %s[%d]%s(%p,%d,%s[%p])\n",
232 timestamp, execname, pid, probename,
233 arg0, arg1, rep[staticCode[arg2].rep].path, arg2);
234 code[arg0].staticCode = arg2;
235 }
236
237 codesign$1:::guest-cdhash-*
238 {
239 self->hash = code[arg0].hash = (uint8_t *)copyin(arg1, sizeof(Hash));
240 printf("%8u %s[%d]%s(%p,H\"%02x%02x%02x...%02x%02x\")\n",
241 timestamp, execname, pid, probename, arg0,
242 self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
243 }
244
245 codesign$1:::static-cdhash
246 {
247 self->hash = staticCode[arg0].hash = (uint8_t *)copyin(arg1, sizeof(Hash));
248 printf("%8u %s[%d]%s(%p,H\"%02x%02x%02x...%02x%02x\")\n",
249 timestamp, execname, pid, probename, arg0,
250 self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
251 }
252
253
254 /*
255 * Guest registry/proxy management in securityd
256 */
257 typedef struct {
258 DTHandle guest;
259 string path;
260 uint32_t status;
261 uint8_t *hash;
262 } SDGuest;
263 SDGuest guests[DTHandle, DTHandle]; /* host x guest */
264
265 securityd*:::host-register
266 {
267 printf("%8u HOST DYNAMIC(%p,%d)\n",
268 timestamp, arg0, arg1);
269 }
270
271 securityd*:::host-proxy
272 {
273 printf("%8u HOST PROXY(%p,%d)\n",
274 timestamp, arg0, arg1);
275 }
276
277 securityd*:::host-unregister
278 {
279 printf("%8u HOST DESTROYED(%p)\n",
280 timestamp, arg0);
281 }
282
283 securityd*:::guest-create
284 {
285 guests[arg0, arg2].guest = arg2;
286 guests[arg0, arg2].path = copyinstr(arg5);
287 guests[arg0, arg2].status = arg3;
288 printf("%8u GUEST CREATE(%p,%s[0x%x],host=0x%x,status=0x%x,flags=%d)\n",
289 timestamp,
290 arg0, guests[arg0, arg2].path, arg2, arg1, arg3, arg4);
291 }
292
293 securityd*:::guest-cdhash
294 / arg2 != 0 /
295 {
296 self->hash = guests[arg0, arg1].hash = (uint8_t *)copyin(arg2, sizeof(Hash));
297 printf("%8u GUEST HASH(%p,%s[0x%x],H\"%02x%02x%02x...%02x%02x\")\n",
298 timestamp,
299 arg0, guests[arg0, arg1].path, arg1,
300 self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
301 }
302
303 securityd*:::guest-cdhash
304 / arg2 == 0 /
305 {
306 printf("%8u GUEST HASH(%p,%s[0x%x],NONE)\n",
307 timestamp, arg0, guests[arg0, arg1].path, arg1);
308 }
309
310 securityd*:::guest-change
311 {
312 printf("%8u GUEST CHANGE(%p,%s[0x%x],status=0x%x)\n",
313 timestamp,
314 arg0, guests[arg0, arg1].path, arg1, arg2);
315 }
316
317 securityd*:::guest-destroy
318 {
319 printf("%8u GUEST DESTROY(%p,%s[0x%x])\n",
320 timestamp,
321 arg0, guests[arg0, arg1].path, arg1);
322 }
323
324
325 /*
326 * Signing Mach-O allocation tracking
327 */
328 codesign$1:::allocate-arch
329 {
330 printf("%8u %s[%d]%s(%s,%d)\n",
331 timestamp, execname, pid, probename, copyinstr(arg0), arg1);
332 }
333
334 codesign$1:::allocate-archn
335 {
336 printf("%8u %s[%d]%s((0x%x,0x%x),%d)\n",
337 timestamp, execname, pid, probename, arg0, arg1, arg2);
338 }
339
340 codesign$1:::allocate-write
341 {
342 printf("%8u %s[%d]%s(%s,offset 0x%x,%d of %d)\n",
343 timestamp, execname, pid, probename,
344 copyinstr(arg0), arg1, arg2, arg3);
345 }
346
347 codesign$1:::allocate-validate
348 {
349 printf("%8u %s[%d]%s(%s,%d)\n",
350 timestamp, execname, pid, probename, copyinstr(arg0), arg1);
351 }
352
353
354 /*
355 * Evaluation tracking
356 */
357 codesign$1:::eval-dynamic-start
358 {
359 printf("%8u %s[%d]%s(%p,%s)\n",
360 timestamp, execname, pid, probename, arg0, copyinstr(arg1));
361 }
362
363 codesign$1:::eval-dynamic-end
364 {
365 printf("%8u %s[%d]%s(%p)\n",
366 timestamp, execname, pid, probename, arg0);
367 }
368