1#!/usr/sbin/dtrace -q -s 2 3 4 5/* 6 * Tracking state 7 */ 8typedef uint32_t DTPort; 9typedef uint64_t DTHandle; 10 11DTHandle portmap[DTPort]; /* map client reply ports to connections */ 12 13struct connection { 14 DTPort replyport; /* reply port for client thread */ 15 uint32_t client; /* client object for this connection */ 16}; 17struct connection connection[DTHandle]; /* indexed by connection handle */ 18 19/* should be a single self struct, but that doesn't work right... */ 20self string reqName; /* request name */ 21self DTHandle reqConnection; /* associated connection */ 22self DTHandle reqClient; /* associated client */ 23 24struct client { 25 pid_t pid; /* original client pid */ 26 DTHandle session; /* session handle */ 27 string name; /* abbreviated name */ 28 string path; /* path to client process (regardless of guests) */ 29 DTPort taskport; /* process task port */ 30}; 31struct client client[DTHandle]; /* indexed by client handle */ 32 33struct keychain { 34 string name; /* keychain path */ 35}; 36struct keychain keychain[DTHandle]; /* indexed by DbCommon handle */ 37 38 39/* 40 * Script management 41 */ 42:::BEGIN 43{ 44 /* fake data for unknown processes */ 45 client[0].pid = 0; 46 client[0].session = 0; 47 client[0].name = "*UNKNOWN*"; 48 client[0].path = "*UNKNOWN*"; 49 50 printf("Ready...\n"); 51} 52 53 54/* 55 * Translate thread id 56 */ 57uint32_t threads[DTHandle]; /* map tids to simple thread numbers */ 58uint32_t nextThread; /* next unused thread number */ 59self uint32_t mytid; /* translated tid */ 60 61securityd*::: /!threads[tid]/ { threads[tid] = ++nextThread; } 62security_debug*::: /!threads[tid]/ { threads[tid] = ++nextThread; } 63 64securityd*::: { self->mytid = threads[tid]; } 65security_debug*::: { self->mytid = threads[tid]; } 66 67 68/* 69 * Principal events 70 */ 71securityd*:::installmode 72{ 73 printf("%u SYSTEM INSTALLATION MODE SELECTED\n", timestamp); 74} 75 76securityd*:::initialized 77{ 78 printf("%u COMMENCING SERVICE as %s\n", timestamp, copyinstr(arg0)); 79} 80 81 82/* 83 * Client management 84 */ 85securityd*:::client-connection-new 86{ 87 replymap[arg1] = arg0; 88 self->reqClient = arg2; 89 connection[arg0].client = self->reqClient; 90 self->reqConnection = arg0; 91 @total["Connections"] = count(); 92 printf("%u T%d:connection-new(<%x>,port=%d,client=<%x>/%s(%d))\n", 93 timestamp, self->mytid, arg0, arg1, 94 arg2, client[arg2].name, client[arg2].pid); 95} 96 97securityd*:::client-connection-release 98/connection[arg0].client/ 99{ 100 printf("%u T%d:connection-release(<%x>,client=<%x>/%s(%d))\n", 101 timestamp, self->mytid, arg0, 102 connection[arg0].client, 103 client[connection[arg0].client].name, 104 client[connection[arg0].client].pid); 105 replymap[connection[arg0].replyport] = 0; /* clear from port map */ 106 connection[arg0].replyport = 0; 107 connection[arg0].client = 0; 108} 109 110securityd*:::client-new 111{ 112 client[arg0].pid = arg1; 113 client[arg0].session = arg2; 114 client[arg0].path = copyinstr(arg3); 115 client[arg0].name = basename(client[arg0].path); 116 client[arg0].taskport = arg4; 117 self->reqClient = arg0; 118 @total["Processes"] = count(); 119 printf("%u T%d:client-new(<%x>,%s(%d),session=<%x>,task=%d)\n", 120 timestamp, self->mytid, arg0, 121 client[arg0].path, client[arg0].pid, 122 client[arg0].session, client[arg0].taskport); 123} 124 125securityd*:::client-release 126{ 127 printf("%u T%d:client-release(<%x>,%s(%d))\n", 128 timestamp, self->mytid, arg0, client[arg0].path, arg1); 129 client[arg0].pid = 0; 130} 131 132securityd*:::client-change_session 133{ 134 printf("%u T%d:client-change_session(<%x>,new session=<%x>)\n", 135 timestamp, self->mytid, arg0, arg1); 136 client[arg0].pid = 0; 137} 138 139 140/* 141 * Client requests 142 */ 143uint32_t connections[DTHandle]; 144uint32_t nextConnection; 145self uint32_t myConnection; 146 147securityd*:::request-entry 148/!connections[arg1]/ 149{ connections[arg1] = ++nextConnection; } 150 151securityd*:::request-entry 152{ 153 self->reqName = copyinstr(arg0); 154 self->reqConnection = arg1; 155 self->myConnection = connections[arg1]; 156 self->reqClient = arg2; 157 this->client = client[self->reqClient]; 158} 159 160securityd*:::request-entry 161/this->client.pid/ 162{ 163 printf("%u T%d:C%d:%s(%d)%s\n", 164 timestamp, self->mytid, self->myConnection, this->client.name, this->client.pid, self->reqName); 165 @request[client[self->reqClient].name, self->reqName] = count(); 166} 167 168securityd*:::request-entry 169/!this->client.pid/ 170{ 171 printf("%u T%d:C%d:%s\n", 172 timestamp, self->mytid, self->myConnection, self->reqName); 173} 174 175securityd*:::request-entry 176{ 177 @requests[self->reqName] = count(); 178 @total["Requests"] = count(); 179} 180 181securityd*:::request-return 182/self->reqConnection && arg0 == 0/ 183{ 184 printf("%u T%d:C%d:return\n", 185 timestamp, self->mytid, self->myConnection); 186} 187 188securityd*:::request-return 189/self->reqConnection && arg0 != 0/ 190{ 191 printf("%u T%d:C%d:FAIL(%d)\n", 192 timestamp, self->mytid, self->myConnection, arg0); 193} 194 195securityd*:::request-return 196{ 197 self->reqConnection = 0; 198 self->reqClient = 0; 199} 200 201 202/* 203 * Sessions 204 */ 205typedef uint32_t SessionId; 206 207struct Session { 208 DTHandle handle; 209 SessionId sessionid; 210}; 211struct Session session[SessionId]; 212 213struct xauditinfo { 214 uint32_t ai_auid; /* audit user id */ 215 struct { 216 unsigned int low; 217 unsigned int high; 218 } ai_mask; 219 struct { 220 uint32_t dev; 221 uint32_t type; 222 uint32_t addr[4]; 223 } ai_termid; 224 au_asid_t ai_asid; /* audit session id */ 225 au_asflgs_t ai_flags; /* audit session flags */ 226}; 227self struct xauditinfo *ai; 228 229securityd*:::session-create 230{ 231 session[arg1].handle = arg0; 232 session[arg1].sessionid = arg1; 233 self->ai = copyin(arg2, sizeof(struct xauditinfo)); 234 printf("%u T%d:%s(<%x>,id=%d,uid=%d,flags=%#x)\n", timestamp, self->mytid, probename, 235 arg0, arg1, self->ai->ai_auid, self->ai->ai_flags); 236} 237 238securityd*:::session-kill 239{ 240 printf("%u T%d:%s(<%x>,id=%d)\n", timestamp, self->mytid, probename, arg0, arg1); 241} 242 243securityd*:::session-destroy 244{ 245 printf("%u T%d:%s(<%x>,id=%d)\n", timestamp, self->mytid, probename, arg0, arg1); 246} 247 248securityd*:::session-notify 249{ 250 printf("%u T%d:%s(<%x>,id=%d,events=0x%x,uid=%d)\n", timestamp, self->mytid, probename, 251 session[arg0].handle, arg0, arg1, arg2); 252} 253 254 255/* 256 * Keychains 257 */ 258securityd*:::keychain-* 259{ 260 this->path = copyinstr(arg1); 261 printf("%u T%d:%s(<%x>,%s)\n", timestamp, self->mytid, probename, arg0, this->path); 262 @keychain[this->path, probename] = count(); 263} 264 265 266/* 267 * Low-level port events 268 */ 269securityd*:::ports-* 270{ 271 printf("%u T%d:%s(%d)\n", timestamp, self->mytid, probename, arg0); 272} 273 274 275/* 276 * Code signing 277 */ 278securityd*:::guest-create 279{ 280 printf("%u T%d:guest-create(<%x>,host=<%x>,guest=<%x>,status=0x%x,flags=0x%x,path=%s)\n", 281 timestamp, self->mytid, arg0, arg1, arg2, arg3, arg4, copyinstr(arg5)); 282 @total["Guests"] = count(); 283} 284 285securityd*:::guest-change 286{ 287 printf("%u T%d:guest-change(<%x>,<%x>,status=0x%x)\n", timestamp, self->mytid, arg0, arg1, arg2); 288} 289 290securityd*:::guest-destroy 291{ 292 printf("%u T%d:guest-destroy(<%x>,<%x>)\n", timestamp, self->mytid, arg0, arg1); 293} 294 295securityd*:::host-register, 296securityd*:::host-proxy 297{ 298 printf("%u T%d:%s(<%x>,port=%d)\n", timestamp, self->mytid, probename, arg0, arg1); 299 @total["Hosts"] = count(); 300} 301 302securityd*:::host-unregister 303{ 304 printf("%u T%d:host-unregister(<%x>)\n", timestamp, self->mytid, arg0); 305} 306 307 308/* 309 * Child management 310 */ 311securityd*:::child-* 312{ 313 printf("%u T%d:%s(%d,%d)\n", timestamp, self->mytid, probename, arg0, arg1); 314} 315 316 317/* 318 * Power events 319 */ 320securityd*:::power-* 321{ 322 printf("%u T%d:POWER(%s)\n", timestamp, self->mytid, probename); 323} 324 325 326/* 327 * Authorization 328 */ 329securityd*:::auth-create 330{ 331 printf("%u T%d:%s ref(%#x) session(%#x)\n", timestamp, self->mytid, probename, arg1, arg0); 332} 333 334securityd*:::auth-allow, 335securityd*:::auth-deny, 336securityd*:::auth-user, 337securityd*:::auth-rules, 338securityd*:::auth-kofn, 339securityd*:::auth-mechrule 340{ 341 printf("%u T%d:%s ref(%#x) rule(%s)\n", timestamp, self->mytid, probename, arg0, copyinstr(arg1)); 342} 343 344securityd*:::auth-mech 345{ 346 printf("%u T%d:%s ref(%#x) (%s)\n", timestamp, self->mytid, probename, arg0, copyinstr(arg1)); 347} 348 349securityd*:::auth-user-allowroot, 350securityd*:::auth-user-allowsessionowner 351{ 352 printf("%u T%d:%s ref(%#x)\n", timestamp, self->mytid, probename, arg0); 353} 354 355securityd*:::auth-evalright 356{ 357 printf("%u T%d:%s ref(%#x) %s (%d)\n", timestamp, self->mytid, probename, arg0, copyinstr(arg1), arg2); 358} 359 360 361/* 362 * Miscellanea 363 */ 364securityd*:::entropy-collect 365{ 366 printf("%u T%d:entropy-collect()\n", timestamp, tid); 367} 368 369securityd*:::entropy-seed 370{ 371 printf("%u T%d:entropy-seed(%d)\n", timestamp, self->mytid, arg0); 372} 373 374securityd*:::entropy-save 375{ 376 printf("%u T%d:entropy-save(%s)\n", timestamp, self->mytid, copyinstr(arg0)); 377} 378 379securityd*:::signal-* 380{ 381 printf("%u T%d:%s(%d)\n", timestamp, self->mytid, probename, arg0); 382} 383 384 385/* 386 * Integrate secdebug logs 387 */ 388security_debug*:::log 389/execname == "securityd"/ 390{ 391 printf("%u T%d:[%s]%s\n", timestamp, threads[tid], 392 copyinstr(arg0), copyinstr(arg1)); 393} 394 395security_exception*:::throw-* 396/execname == "securityd"/ 397{ 398 printf("%u T%d:EXCEPTION(%p) THROWN %s(%d)\n", timestamp, threads[tid], 399 arg0, probename, arg1); 400} 401 402 403/* 404 * Wrapup 405 */ 406:::END 407{ 408 printa("%@8u %s\n", @total); 409 printf("\n Requests:\n"); 410 printa("%@8u %s\n", @requests); 411 printf("\n Requests by client:\n"); 412 printa("%@8u %s:%s\n", @request); 413 printf("\n Keychains by path and operation:\n"); 414 printa("%@8u %s(%s)\n", @keychain); 415} 416