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