1 /*- 2 * Copyright (c) 2016, 2018 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * This software was developed by BAE Systems, the University of Cambridge 6 * Computer Laboratory, and Memorial University under DARPA/AFRL contract 7 * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing 8 * (TC) research program. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/conf.h> 34 #include <sys/ctype.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/module.h> 38 #include <sys/queue.h> 39 #include <sys/refcount.h> 40 41 #include <sys/dtrace.h> 42 #include <sys/dtrace_bsd.h> 43 44 #include <bsm/audit.h> 45 #include <bsm/audit_internal.h> 46 #include <bsm/audit_kevents.h> 47 48 #include <security/audit/audit.h> 49 #include <security/audit/audit_private.h> 50 51 /*- 52 * Audit DTrace provider: allow DTrace to request that audit records be 53 * generated for various audit events, and then expose those records (in 54 * various forms) to probes. The model is that each event type has two 55 * probes, which use the event's name to create the probe: 56 * 57 * - "commit" passes the kernel-internal (unserialised) kaudit_record 58 * synchronously (from the originating thread) of the record as we prepare 59 * to "commit" the record to the audit queue. 60 * 61 * - "bsm" also passes generated BSM, and executes asynchronously in the audit 62 * worker thread, once it has been extracted from the audit queue. This is 63 * the point at which an audit record would be enqueued to the trail on 64 * disk, or to pipes. 65 * 66 * These probes support very different goals. The former executes in the 67 * thread originating the record, making it easier to correlate other DTrace 68 * probe activity with the event described in the record. The latter gives 69 * access to BSM-formatted events (at a cost) allowing DTrace to extract BSM 70 * directly an alternative mechanism to the formal audit trail and audit 71 * pipes. 72 * 73 * To generate names for numeric event IDs, userspace will push the contents 74 * of /etc/security/audit_event into the kernel during audit setup, much as it 75 * does /etc/security/audit_class. We then create the probes for each of 76 * those mappings. If one (or both) of the probes are enabled, then we cause 77 * a record to be generated (as both normal audit preselection and audit pipes 78 * do), and catch it on the way out during commit. There are suitable hook 79 * functions in the audit code that this provider can register to catch 80 * various events in the audit-record life cycle. 81 * 82 * Further ponderings: 83 * 84 * - How do we want to handle events for which there are not names -- perhaps 85 * a catch-all probe for those events without mappings? 86 * 87 * - Should the evname code really be present even if DTrace isn't loaded...? 88 * Right now, we arrange that it is so that userspace can usefully maintain 89 * the list in case DTrace is later loaded (and to prevent userspace 90 * confusion). 91 * 92 * - Should we add an additional set of audit:class::commit probes that use 93 * event class names to match broader categories of events as specified in 94 * /etc/security/event_class? 95 * 96 * - If we pursue that last point, we will want to pass the name of the event 97 * into the probe explicitly (e.g., as arg0), since it would no longer be 98 * available as the probe function name. 99 */ 100 101 static int dtaudit_unload(void); 102 static void dtaudit_getargdesc(void *, dtrace_id_t, void *, 103 dtrace_argdesc_t *); 104 static void dtaudit_provide(void *, dtrace_probedesc_t *); 105 static void dtaudit_destroy(void *, dtrace_id_t, void *); 106 static void dtaudit_enable(void *, dtrace_id_t, void *); 107 static void dtaudit_disable(void *, dtrace_id_t, void *); 108 static void dtaudit_load(void *); 109 110 static dtrace_pattr_t dtaudit_attr = { 111 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 112 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 113 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 114 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 115 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 116 }; 117 118 /* 119 * Strings for the "module" and "name" portions of the probe. The name of the 120 * audit event will be the "function" portion of the probe. All dtaudit 121 * probes therefore take the form audit:event:<event name>:commit. 122 */ 123 static char *dtaudit_module_str = "event"; 124 static char *dtaudit_name_commit_str = "commit"; 125 static char *dtaudit_name_bsm_str = "bsm"; 126 127 static dtrace_pops_t dtaudit_pops = { 128 .dtps_provide = dtaudit_provide, 129 .dtps_provide_module = NULL, 130 .dtps_enable = dtaudit_enable, 131 .dtps_disable = dtaudit_disable, 132 .dtps_suspend = NULL, 133 .dtps_resume = NULL, 134 .dtps_getargdesc = dtaudit_getargdesc, 135 .dtps_getargval = NULL, 136 .dtps_usermode = NULL, 137 .dtps_destroy = dtaudit_destroy 138 }; 139 140 static dtrace_provider_id_t dtaudit_id; 141 142 /* 143 * Because looking up entries in the event-to-name mapping is quite expensive, 144 * maintain a global flag tracking whether any dtaudit probes are enabled. If 145 * not, don't bother doing all that work whenever potential queries about 146 * events turn up during preselection or commit. 147 * 148 * NB: We used to maintain our own variable in dtaudit, but now use the 149 * centralized audit_dtrace_enabled variable imported from the audit code. 150 * 151 * static uint_t dtaudit_probes_enabled; 152 */ 153 154 /* 155 * Check dtaudit policy for the event to see whether this is an event we would 156 * like to preselect (i.e., cause an audit record to be generated for). To 157 * minimise probe effect when not used at all, we not only check for the probe 158 * on the individual event, but also a global flag indicating that at least 159 * one probe is enabled, before acquiring locks, searching lists, etc. 160 * 161 * If the event is selected, return an evname_elem reference to be stored in 162 * the audit record, which we can use later to avoid further lookups. The 163 * contents of the evname_elem must be sufficiently stable so as to not risk 164 * race conditions here. 165 * 166 * Currently, we take an interest only in the 'event' argument, but in the 167 * future might want to support other types of record selection tied to 168 * additional probe types (e.g., event clases). 169 * 170 * XXXRW: Should we have a catch-all probe here for events without registered 171 * names? 172 */ 173 static void * 174 dtaudit_preselect(au_id_t auid, au_event_t event, au_class_t class) 175 { 176 struct evname_elem *ene; 177 int probe_enabled; 178 179 /* 180 * NB: Lockless reads here may return a slightly stale value; this is 181 * considered better than acquiring a lock, however. 182 */ 183 if (!audit_dtrace_enabled) 184 return (NULL); 185 ene = au_evnamemap_lookup(event); 186 if (ene == NULL) 187 return (NULL); 188 189 /* 190 * See if either of the two probes for the audit event are enabled. 191 * 192 * NB: Lock also not acquired here -- but perhaps it wouldn't matter 193 * given that we've already used the list lock above? 194 * 195 * XXXRW: Alternatively, au_evnamemap_lookup() could return these 196 * values while holding the list lock...? 197 */ 198 probe_enabled = ene->ene_commit_probe_enabled || 199 ene->ene_bsm_probe_enabled; 200 if (!probe_enabled) 201 return (NULL); 202 return ((void *)ene); 203 } 204 205 /* 206 * Commit probe pre-BSM. Fires the probe but also checks to see if we should 207 * ask the audit framework to call us again with BSM arguments in the audit 208 * worker thread. 209 * 210 * XXXRW: Should we have a catch-all probe here for events without registered 211 * names? 212 */ 213 static int 214 dtaudit_commit(struct kaudit_record *kar, au_id_t auid, au_event_t event, 215 au_class_t class, int sorf) 216 { 217 char ene_name_lower[EVNAMEMAP_NAME_SIZE]; 218 struct evname_elem *ene; 219 int i; 220 221 ene = (struct evname_elem *)kar->k_dtaudit_state; 222 if (ene == NULL) 223 return (0); 224 225 /* 226 * Process a possibly registered commit probe. 227 */ 228 if (ene->ene_commit_probe_enabled) { 229 /* 230 * XXXRW: Lock ene to provide stability to the name string. A 231 * bit undesirable! We may want another locking strategy 232 * here. At least we don't run the DTrace probe under the 233 * lock. 234 * 235 * XXXRW: We provide the struct audit_record pointer -- but 236 * perhaps should provide the kaudit_record pointer? 237 */ 238 EVNAME_LOCK(ene); 239 for (i = 0; i < sizeof(ene_name_lower); i++) 240 ene_name_lower[i] = tolower(ene->ene_name[i]); 241 EVNAME_UNLOCK(ene); 242 dtrace_probe(ene->ene_commit_probe_id, 243 (uintptr_t)ene_name_lower, (uintptr_t)&kar->k_ar, 0, 0, 0); 244 } 245 246 /* 247 * Return the state of the BSM probe to the caller. 248 */ 249 return (ene->ene_bsm_probe_enabled); 250 } 251 252 /* 253 * Commit probe post-BSM. 254 * 255 * XXXRW: Should we have a catch-all probe here for events without registered 256 * names? 257 */ 258 static void 259 dtaudit_bsm(struct kaudit_record *kar, au_id_t auid, au_event_t event, 260 au_class_t class, int sorf, void *bsm_data, size_t bsm_len) 261 { 262 char ene_name_lower[EVNAMEMAP_NAME_SIZE]; 263 struct evname_elem *ene; 264 int i; 265 266 ene = (struct evname_elem *)kar->k_dtaudit_state; 267 if (ene == NULL) 268 return; 269 if (!(ene->ene_bsm_probe_enabled)) 270 return; 271 272 /* 273 * XXXRW: Lock ene to provide stability to the name string. A bit 274 * undesirable! We may want another locking strategy here. At least 275 * we don't run the DTrace probe under the lock. 276 * 277 * XXXRW: We provide the struct audit_record pointer -- but perhaps 278 * should provide the kaudit_record pointer? 279 */ 280 EVNAME_LOCK(ene); 281 for (i = 0; i < sizeof(ene_name_lower); i++) 282 ene_name_lower[i] = tolower(ene->ene_name[i]); 283 EVNAME_UNLOCK(ene); 284 dtrace_probe(ene->ene_bsm_probe_id, (uintptr_t)ene_name_lower, 285 (uintptr_t)&kar->k_ar, (uintptr_t)bsm_data, (uintptr_t)bsm_len, 286 0); 287 } 288 289 /* 290 * A very simple provider: argument types are identical across all probes: the 291 * kaudit_record, plus a BSM pointer and length. 292 */ 293 static void 294 dtaudit_getargdesc(void *arg, dtrace_id_t id, void *parg, 295 dtrace_argdesc_t *desc) 296 { 297 struct evname_elem *ene; 298 const char *p; 299 300 ene = (struct evname_elem *)parg; 301 p = NULL; 302 switch (desc->dtargd_ndx) { 303 case 0: 304 /* Audit event name. */ 305 p = "char *"; 306 break; 307 308 case 1: 309 /* In-kernel audit record. */ 310 p = "struct audit_record *"; 311 break; 312 313 case 2: 314 /* BSM data, if present. */ 315 if (id == ene->ene_bsm_probe_id) 316 p = "const void *"; 317 else 318 desc->dtargd_ndx = DTRACE_ARGNONE; 319 break; 320 321 case 3: 322 /* BSM length, if present. */ 323 if (id == ene->ene_bsm_probe_id) 324 p = "size_t"; 325 else 326 desc->dtargd_ndx = DTRACE_ARGNONE; 327 break; 328 329 default: 330 desc->dtargd_ndx = DTRACE_ARGNONE; 331 break; 332 } 333 if (p != NULL) 334 strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native)); 335 } 336 337 /* 338 * Callback from the event-to-name mapping code when performing 339 * evname_foreach(). Note that we may update the entry, so the foreach code 340 * must have a write lock. However, as the synchronisation model is private 341 * to the evname code, we cannot easily assert it here. 342 * 343 * XXXRW: How do we want to handle event rename / collision issues here -- 344 * e.g., if userspace was using a name to point to one event number, and then 345 * changes it so that the name points at another? For now, paper over this by 346 * skipping event numbers that are already registered, and likewise skipping 347 * names that are already registered. However, this could lead to confusing 348 * behaviour so possibly needs to be resolved in the longer term. 349 */ 350 static void 351 dtaudit_au_evnamemap_callback(struct evname_elem *ene) 352 { 353 char ene_name_lower[EVNAMEMAP_NAME_SIZE]; 354 int i; 355 356 /* 357 * DTrace, by convention, has lower-case probe names. However, the 358 * in-kernel event-to-name mapping table must maintain event-name case 359 * as submitted by userspace. Create a temporary lower-case version 360 * here, away from the fast path, to use when exposing the event name 361 * to DTrace as part of the name of a probe. 362 * 363 * NB: Convert the entire array, including the terminating nul, 364 * because these strings are short and it's more work not to. If they 365 * become long, we might feel more guilty about this sloppiness! 366 */ 367 for (i = 0; i < sizeof(ene_name_lower); i++) 368 ene_name_lower[i] = tolower(ene->ene_name[i]); 369 370 /* 371 * Don't register a new probe if this event number already has an 372 * associated commit probe -- or if another event has already 373 * registered this name. 374 * 375 * XXXRW: There is an argument that if multiple numeric events match 376 * a single name, they should all be exposed to the same named probe. 377 * In particular, we should perhaps use a probe ID returned by this 378 * lookup and just stick that in the saved probe ID? 379 */ 380 if ((ene->ene_commit_probe_id == 0) && 381 (dtrace_probe_lookup(dtaudit_id, dtaudit_module_str, 382 ene_name_lower, dtaudit_name_commit_str) == 0)) { 383 /* 384 * Create the commit probe. 385 * 386 * NB: We don't declare any extra stack frames because stack() 387 * will just return the path to the audit commit code, which 388 * is not really interesting anyway. 389 * 390 * We pass in the pointer to the evnam_elem entry so that we 391 * can easily change its enabled flag in the probe 392 * enable/disable interface. 393 */ 394 ene->ene_commit_probe_id = dtrace_probe_create(dtaudit_id, 395 dtaudit_module_str, ene_name_lower, 396 dtaudit_name_commit_str, 0, ene); 397 } 398 399 /* 400 * Don't register a new probe if this event number already has an 401 * associated bsm probe -- or if another event has already 402 * registered this name. 403 * 404 * XXXRW: There is an argument that if multiple numeric events match 405 * a single name, they should all be exposed to the same named probe. 406 * In particular, we should perhaps use a probe ID returned by this 407 * lookup and just stick that in the saved probe ID? 408 */ 409 if ((ene->ene_bsm_probe_id == 0) && 410 (dtrace_probe_lookup(dtaudit_id, dtaudit_module_str, 411 ene_name_lower, dtaudit_name_bsm_str) == 0)) { 412 /* 413 * Create the bsm probe. 414 * 415 * NB: We don't declare any extra stack frames because stack() 416 * will just return the path to the audit commit code, which 417 * is not really interesting anyway. 418 * 419 * We pass in the pointer to the evnam_elem entry so that we 420 * can easily change its enabled flag in the probe 421 * enable/disable interface. 422 */ 423 ene->ene_bsm_probe_id = dtrace_probe_create(dtaudit_id, 424 dtaudit_module_str, ene_name_lower, dtaudit_name_bsm_str, 425 0, ene); 426 } 427 } 428 429 static void 430 dtaudit_provide(void *arg, dtrace_probedesc_t *desc) 431 { 432 433 /* 434 * Walk all registered number-to-name mapping entries, and ensure each 435 * is properly registered. 436 */ 437 au_evnamemap_foreach(dtaudit_au_evnamemap_callback); 438 } 439 440 static void 441 dtaudit_destroy(void *arg, dtrace_id_t id, void *parg) 442 { 443 } 444 445 static void 446 dtaudit_enable(void *arg, dtrace_id_t id, void *parg) 447 { 448 struct evname_elem *ene; 449 450 ene = parg; 451 KASSERT(ene->ene_commit_probe_id == id || ene->ene_bsm_probe_id == id, 452 ("%s: probe ID mismatch (%u, %u != %u)", __func__, 453 ene->ene_commit_probe_id, ene->ene_bsm_probe_id, id)); 454 455 if (id == ene->ene_commit_probe_id) 456 ene->ene_commit_probe_enabled = 1; 457 else 458 ene->ene_bsm_probe_enabled = 1; 459 refcount_acquire(&audit_dtrace_enabled); 460 audit_syscalls_enabled_update(); 461 } 462 463 static void 464 dtaudit_disable(void *arg, dtrace_id_t id, void *parg) 465 { 466 struct evname_elem *ene; 467 468 ene = parg; 469 KASSERT(ene->ene_commit_probe_id == id || ene->ene_bsm_probe_id == id, 470 ("%s: probe ID mismatch (%u, %u != %u)", __func__, 471 ene->ene_commit_probe_id, ene->ene_bsm_probe_id, id)); 472 473 if (id == ene->ene_commit_probe_id) 474 ene->ene_commit_probe_enabled = 0; 475 else 476 ene->ene_bsm_probe_enabled = 0; 477 (void)refcount_release(&audit_dtrace_enabled); 478 audit_syscalls_enabled_update(); 479 } 480 481 static void 482 dtaudit_load(void *dummy) 483 { 484 485 if (dtrace_register("audit", &dtaudit_attr, DTRACE_PRIV_USER, NULL, 486 &dtaudit_pops, NULL, &dtaudit_id) != 0) 487 return; 488 dtaudit_hook_preselect = dtaudit_preselect; 489 dtaudit_hook_commit = dtaudit_commit; 490 dtaudit_hook_bsm = dtaudit_bsm; 491 } 492 493 static int 494 dtaudit_unload(void) 495 { 496 int error; 497 498 dtaudit_hook_preselect = NULL; 499 dtaudit_hook_commit = NULL; 500 dtaudit_hook_bsm = NULL; 501 if ((error = dtrace_unregister(dtaudit_id)) != 0) 502 return (error); 503 return (0); 504 } 505 506 static int 507 dtaudit_modevent(module_t mod __unused, int type, void *data __unused) 508 { 509 int error = 0; 510 511 switch (type) { 512 case MOD_LOAD: 513 case MOD_UNLOAD: 514 case MOD_SHUTDOWN: 515 break; 516 517 default: 518 error = EOPNOTSUPP; 519 break; 520 } 521 522 return (error); 523 } 524 525 SYSINIT(dtaudit_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, dtaudit_load, 526 NULL); 527 SYSUNINIT(dtaudit_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, 528 dtaudit_unload, NULL); 529 530 DEV_MODULE(dtaudit, dtaudit_modevent, NULL); 531 MODULE_VERSION(dtaudit, 1); 532 MODULE_DEPEND(dtaudit, dtrace, 1, 1, 1); 533 MODULE_DEPEND(dtaudit, opensolaris, 1, 1, 1); 534