1/*- 2 * Copyright (c) 1999-2009 Apple Inc. 3 * Copyright (c) 2006-2007 Robert N. M. Watson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31/* 32 * NOTICE: This file was modified by McAfee Research in 2004 to introduce 33 * support for mandatory and extensible security protections. This notice 34 * is included in support of clause 2.2 (b) of the Apple Public License, 35 * Version 2.0. 36 */ 37 38#include <sys/param.h> 39#include <sys/fcntl.h> 40#include <sys/kernel.h> 41#include <sys/lock.h> 42#include <sys/namei.h> 43#include <sys/proc_internal.h> 44#include <sys/kauth.h> 45#include <sys/queue.h> 46#include <sys/systm.h> 47#include <sys/time.h> 48#include <sys/ucred.h> 49#include <sys/uio.h> 50#include <sys/unistd.h> 51#include <sys/file_internal.h> 52#include <sys/vnode_internal.h> 53#include <sys/user.h> 54#include <sys/syscall.h> 55#include <sys/malloc.h> 56#include <sys/un.h> 57#include <sys/sysent.h> 58#include <sys/sysproto.h> 59#include <sys/vfs_context.h> 60#include <sys/domain.h> 61#include <sys/protosw.h> 62#include <sys/socketvar.h> 63 64#include <bsm/audit.h> 65#include <bsm/audit_internal.h> 66#include <bsm/audit_kevents.h> 67 68#include <security/audit/audit.h> 69#include <security/audit/audit_bsd.h> 70#include <security/audit/audit_private.h> 71 72#include <mach/host_priv.h> 73#include <mach/host_special_ports.h> 74#include <mach/audit_triggers_server.h> 75 76#include <kern/host.h> 77#include <kern/kalloc.h> 78#include <kern/zalloc.h> 79#include <kern/lock.h> 80#include <kern/wait_queue.h> 81#include <kern/sched_prim.h> 82 83#include <net/route.h> 84 85#include <netinet/in.h> 86#include <netinet/in_pcb.h> 87 88#if CONFIG_AUDIT 89MALLOC_DEFINE(M_AUDITDATA, "audit_data", "Audit data storage"); 90MALLOC_DEFINE(M_AUDITPATH, "audit_path", "Audit path storage"); 91MALLOC_DEFINE(M_AUDITTEXT, "audit_text", "Audit text storage"); 92 93/* 94 * Audit control settings that are set/read by system calls and are hence 95 * non-static. 96 * 97 * Define the audit control flags. 98 */ 99int audit_enabled; 100int audit_suspended; 101 102int audit_syscalls; 103au_class_t audit_kevent_mask; 104 105/* 106 * Flags controlling behavior in low storage situations. Should we panic if 107 * a write fails? Should we fail stop if we're out of disk space? 108 */ 109int audit_panic_on_write_fail; 110int audit_fail_stop; 111int audit_argv; 112int audit_arge; 113 114/* 115 * Are we currently "failing stop" due to out of disk space? 116 */ 117int audit_in_failure; 118 119/* 120 * Global audit statistics. 121 */ 122struct audit_fstat audit_fstat; 123 124/* 125 * Preselection mask for non-attributable events. 126 */ 127struct au_mask audit_nae_mask; 128 129/* 130 * Mutex to protect global variables shared between various threads and 131 * processes. 132 */ 133struct mtx audit_mtx; 134 135/* 136 * Queue of audit records ready for delivery to disk. We insert new records 137 * at the tail, and remove records from the head. Also, a count of the 138 * number of records used for checking queue depth. In addition, a counter 139 * of records that we have allocated but are not yet in the queue, which is 140 * needed to estimate the total size of the combined set of records 141 * outstanding in the system. 142 */ 143struct kaudit_queue audit_q; 144int audit_q_len; 145int audit_pre_q_len; 146 147/* 148 * Audit queue control settings (minimum free, low/high water marks, etc.) 149 */ 150struct au_qctrl audit_qctrl; 151 152/* 153 * Condition variable to signal to the worker that it has work to do: either 154 * new records are in the queue, or a log replacement is taking place. 155 */ 156struct cv audit_worker_cv; 157 158/* 159 * Condition variable to signal when the worker is done draining the audit 160 * queue. 161 */ 162struct cv audit_drain_cv; 163 164/* 165 * Condition variable to flag when crossing the low watermark, meaning that 166 * threads blocked due to hitting the high watermark can wake up and continue 167 * to commit records. 168 */ 169struct cv audit_watermark_cv; 170 171/* 172 * Condition variable for auditing threads wait on when in fail-stop mode. 173 * Threads wait on this CV forever (and ever), never seeing the light of day 174 * again. 175 */ 176static struct cv audit_fail_cv; 177 178static zone_t audit_record_zone; 179 180/* 181 * Kernel audit information. This will store the current audit address 182 * or host information that the kernel will use when it's generating 183 * audit records. This data is modified by the A_GET{SET}KAUDIT auditon(2) 184 * command. 185 */ 186static struct auditinfo_addr audit_kinfo; 187static struct rwlock audit_kinfo_lock; 188 189#define KINFO_LOCK_INIT() rw_init(&audit_kinfo_lock, \ 190 "audit_kinfo_lock") 191#define KINFO_RLOCK() rw_rlock(&audit_kinfo_lock) 192#define KINFO_WLOCK() rw_wlock(&audit_kinfo_lock) 193#define KINFO_RUNLOCK() rw_runlock(&audit_kinfo_lock) 194#define KINFO_WUNLOCK() rw_wunlock(&audit_kinfo_lock) 195 196void 197audit_set_kinfo(struct auditinfo_addr *ak) 198{ 199 200 KASSERT(ak->ai_termid.at_type == AU_IPv4 || 201 ak->ai_termid.at_type == AU_IPv6, 202 ("audit_set_kinfo: invalid address type")); 203 204 KINFO_WLOCK(); 205 bcopy(ak, &audit_kinfo, sizeof(audit_kinfo)); 206 KINFO_WUNLOCK(); 207} 208 209void 210audit_get_kinfo(struct auditinfo_addr *ak) 211{ 212 213 KASSERT(audit_kinfo.ai_termid.at_type == AU_IPv4 || 214 audit_kinfo.ai_termid.at_type == AU_IPv6, 215 ("audit_set_kinfo: invalid address type")); 216 217 KINFO_RLOCK(); 218 bcopy(&audit_kinfo, ak, sizeof(*ak)); 219 KINFO_RUNLOCK(); 220} 221 222/* 223 * Construct an audit record for the passed thread. 224 */ 225static void 226audit_record_ctor(proc_t p, struct kaudit_record *ar) 227{ 228 kauth_cred_t cred; 229 230 bzero(ar, sizeof(*ar)); 231 ar->k_ar.ar_magic = AUDIT_RECORD_MAGIC; 232 nanotime(&ar->k_ar.ar_starttime); 233 234 if (PROC_NULL != p) { 235 cred = kauth_cred_proc_ref(p); 236 237 /* 238 * Export the subject credential. 239 */ 240 cru2x(cred, &ar->k_ar.ar_subj_cred); 241 ar->k_ar.ar_subj_ruid = kauth_cred_getruid(cred); 242 ar->k_ar.ar_subj_rgid = kauth_cred_getrgid(cred); 243 ar->k_ar.ar_subj_egid = kauth_cred_getgid(cred); 244 ar->k_ar.ar_subj_pid = p->p_pid; 245 ar->k_ar.ar_subj_auid = cred->cr_audit.as_aia_p->ai_auid; 246 ar->k_ar.ar_subj_asid = cred->cr_audit.as_aia_p->ai_asid; 247 bcopy(&cred->cr_audit.as_mask, &ar->k_ar.ar_subj_amask, 248 sizeof(struct au_mask)); 249 bcopy(&cred->cr_audit.as_aia_p->ai_termid, 250 &ar->k_ar.ar_subj_term_addr, sizeof(struct au_tid_addr)); 251 kauth_cred_unref(&cred); 252 } 253} 254 255static void 256audit_record_dtor(struct kaudit_record *ar) 257{ 258 259 if (ar->k_ar.ar_arg_upath1 != NULL) 260 free(ar->k_ar.ar_arg_upath1, M_AUDITPATH); 261 if (ar->k_ar.ar_arg_upath2 != NULL) 262 free(ar->k_ar.ar_arg_upath2, M_AUDITPATH); 263 if (ar->k_ar.ar_arg_kpath1 != NULL) 264 free(ar->k_ar.ar_arg_kpath1, M_AUDITPATH); 265 if (ar->k_ar.ar_arg_kpath2 != NULL) 266 free(ar->k_ar.ar_arg_kpath2, M_AUDITPATH); 267 if (ar->k_ar.ar_arg_text != NULL) 268 free(ar->k_ar.ar_arg_text, M_AUDITTEXT); 269 if (ar->k_ar.ar_arg_opaque != NULL) 270 free(ar->k_ar.ar_arg_opaque, M_AUDITDATA); 271 if (ar->k_ar.ar_arg_data != NULL) 272 free(ar->k_ar.ar_arg_data, M_AUDITDATA); 273 if (ar->k_udata != NULL) 274 free(ar->k_udata, M_AUDITDATA); 275 if (ar->k_ar.ar_arg_argv != NULL) 276 free(ar->k_ar.ar_arg_argv, M_AUDITTEXT); 277 if (ar->k_ar.ar_arg_envv != NULL) 278 free(ar->k_ar.ar_arg_envv, M_AUDITTEXT); 279} 280 281/* 282 * Initialize the Audit subsystem: configuration state, work queue, 283 * synchronization primitives, worker thread, and trigger device node. Also 284 * call into the BSM assembly code to initialize it. 285 */ 286void 287audit_init(void) 288{ 289 290 audit_enabled = 0; 291 audit_syscalls = 0; 292 audit_kevent_mask = 0; 293 audit_suspended = 0; 294 audit_panic_on_write_fail = 0; 295 audit_fail_stop = 0; 296 audit_in_failure = 0; 297 audit_argv = 0; 298 audit_arge = 0; 299 300 audit_fstat.af_filesz = 0; /* '0' means unset, unbounded. */ 301 audit_fstat.af_currsz = 0; 302 audit_nae_mask.am_success = 0; 303 audit_nae_mask.am_failure = 0; 304 305 TAILQ_INIT(&audit_q); 306 audit_q_len = 0; 307 audit_pre_q_len = 0; 308 audit_qctrl.aq_hiwater = AQ_HIWATER; 309 audit_qctrl.aq_lowater = AQ_LOWATER; 310 audit_qctrl.aq_bufsz = AQ_BUFSZ; 311 audit_qctrl.aq_minfree = AU_FS_MINFREE; 312 313 audit_kinfo.ai_termid.at_type = AU_IPv4; 314 audit_kinfo.ai_termid.at_addr[0] = INADDR_ANY; 315 316 _audit_lck_grp_init(); 317 mtx_init(&audit_mtx, "audit_mtx", NULL, MTX_DEF); 318 KINFO_LOCK_INIT(); 319 cv_init(&audit_worker_cv, "audit_worker_cv"); 320 cv_init(&audit_drain_cv, "audit_drain_cv"); 321 cv_init(&audit_watermark_cv, "audit_watermark_cv"); 322 cv_init(&audit_fail_cv, "audit_fail_cv"); 323 324 audit_record_zone = zinit(sizeof(struct kaudit_record), 325 AQ_HIWATER*sizeof(struct kaudit_record), 8192, "audit_zone"); 326#if CONFIG_MACF 327 audit_mac_init(); 328#endif 329 /* Init audit session subsystem. */ 330 audit_session_init(); 331 332 /* Initialize the BSM audit subsystem. */ 333 kau_init(); 334 335 /* audit_trigger_init(); */ 336 337 /* Start audit worker thread. */ 338 (void) audit_pipe_init(); 339 340 /* Start audit worker thread. */ 341 audit_worker_init(); 342} 343 344/* 345 * Drain the audit queue and close the log at shutdown. Note that this can 346 * be called both from the system shutdown path and also from audit 347 * configuration syscalls, so 'arg' and 'howto' are ignored. 348 */ 349void 350audit_shutdown(void) 351{ 352 353 audit_rotate_vnode(NULL, NULL); 354} 355 356/* 357 * Return the current thread's audit record, if any. 358 */ 359struct kaudit_record * 360currecord(void) 361{ 362 363 return (curthread()->uu_ar); 364} 365 366/* 367 * XXXAUDIT: There are a number of races present in the code below due to 368 * release and re-grab of the mutex. The code should be revised to become 369 * slightly less racy. 370 * 371 * XXXAUDIT: Shouldn't there be logic here to sleep waiting on available 372 * pre_q space, suspending the system call until there is room? 373 */ 374struct kaudit_record * 375audit_new(int event, proc_t p, __unused struct uthread *uthread) 376{ 377 struct kaudit_record *ar; 378 int no_record; 379 int audit_override; 380 381 /* 382 * Override the audit_suspended and audit_enabled if it always 383 * audits session events. 384 * 385 * XXXss - This really needs to be a generalized call to a filter 386 * interface so if other things that use the audit subsystem in the 387 * future can simply plugged in. 388 */ 389 audit_override = (AUE_SESSION_START == event || 390 AUE_SESSION_UPDATE == event || AUE_SESSION_END == event || 391 AUE_SESSION_CLOSE == event); 392 393 mtx_lock(&audit_mtx); 394 no_record = (audit_suspended || !audit_enabled); 395 mtx_unlock(&audit_mtx); 396 if (!audit_override && no_record) 397 return (NULL); 398 399 /* 400 * Initialize the audit record header. 401 * XXX: We may want to fail-stop if allocation fails. 402 * 403 * Note: the number of outstanding uncommitted audit records is 404 * limited to the number of concurrent threads servicing system calls 405 * in the kernel. 406 */ 407 ar = zalloc(audit_record_zone); 408 if (ar == NULL) 409 return NULL; 410 audit_record_ctor(p, ar); 411 ar->k_ar.ar_event = event; 412 413#if CONFIG_MACF 414 if (PROC_NULL != p) { 415 if (audit_mac_new(p, ar) != 0) { 416 zfree(audit_record_zone, ar); 417 return (NULL); 418 } 419 } else 420 ar->k_ar.ar_mac_records = NULL; 421#endif 422 423 mtx_lock(&audit_mtx); 424 audit_pre_q_len++; 425 mtx_unlock(&audit_mtx); 426 427 return (ar); 428} 429 430void 431audit_free(struct kaudit_record *ar) 432{ 433 434 audit_record_dtor(ar); 435#if CONFIG_MACF 436 if (NULL != ar->k_ar.ar_mac_records) 437 audit_mac_free(ar); 438#endif 439 zfree(audit_record_zone, ar); 440} 441 442void 443audit_commit(struct kaudit_record *ar, int error, int retval) 444{ 445 au_event_t event; 446 au_class_t class; 447 au_id_t auid; 448 int sorf; 449 struct au_mask *aumask; 450 int audit_override; 451 452 if (ar == NULL) 453 return; 454 455 /* 456 * Decide whether to commit the audit record by checking the error 457 * value from the system call and using the appropriate audit mask. 458 */ 459 if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) 460 aumask = &audit_nae_mask; 461 else 462 aumask = &ar->k_ar.ar_subj_amask; 463 464 if (error) 465 sorf = AU_PRS_FAILURE; 466 else 467 sorf = AU_PRS_SUCCESS; 468 469 switch(ar->k_ar.ar_event) { 470 case AUE_OPEN_RWTC: 471 /* 472 * The open syscall always writes a AUE_OPEN_RWTC event; 473 * change it to the proper type of event based on the flags 474 * and the error value. 475 */ 476 ar->k_ar.ar_event = audit_flags_and_error_to_openevent( 477 ar->k_ar.ar_arg_fflags, error); 478 break; 479 480 case AUE_OPEN_EXTENDED_RWTC: 481 /* 482 * The open_extended syscall always writes a 483 * AUE_OPEN_EXTENDEDRWTC event; change it to the proper type of 484 * event based on the flags and the error value. 485 */ 486 ar->k_ar.ar_event = audit_flags_and_error_to_openextendedevent( 487 ar->k_ar.ar_arg_fflags, error); 488 break; 489 490 case AUE_SYSCTL: 491 ar->k_ar.ar_event = audit_ctlname_to_sysctlevent( 492 ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); 493 break; 494 495 case AUE_AUDITON: 496 /* Convert the auditon() command to an event. */ 497 ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd); 498 break; 499 500 case AUE_FCNTL: 501 /* Convert some fcntl() commands to their own events. */ 502 ar->k_ar.ar_event = audit_fcntl_command_event( 503 ar->k_ar.ar_arg_cmd, ar->k_ar.ar_arg_fflags, error); 504 break; 505 } 506 507 auid = ar->k_ar.ar_subj_auid; 508 event = ar->k_ar.ar_event; 509 class = au_event_class(event); 510 511 /* 512 * See if we need to override the audit_suspend and audit_enabled 513 * flags. 514 * 515 * XXXss - This check needs to be generalized so new filters can 516 * easily be added. 517 */ 518 audit_override = (AUE_SESSION_START == event || 519 AUE_SESSION_UPDATE == event || AUE_SESSION_END == event || 520 AUE_SESSION_CLOSE == event); 521 522 ar->k_ar_commit |= AR_COMMIT_KERNEL; 523 if (au_preselect(event, class, aumask, sorf) != 0) 524 ar->k_ar_commit |= AR_PRESELECT_TRAIL; 525 if (audit_pipe_preselect(auid, event, class, sorf, 526 ar->k_ar_commit & AR_PRESELECT_TRAIL) != 0) 527 ar->k_ar_commit |= AR_PRESELECT_PIPE; 528 if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE | 529 AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE | 530 AR_PRESELECT_FILTER)) == 0) { 531 mtx_lock(&audit_mtx); 532 audit_pre_q_len--; 533 mtx_unlock(&audit_mtx); 534 audit_free(ar); 535 return; 536 } 537 538 ar->k_ar.ar_errno = error; 539 ar->k_ar.ar_retval = retval; 540 nanotime(&ar->k_ar.ar_endtime); 541 542 /* 543 * Note: it could be that some records initiated while audit was 544 * enabled should still be committed? 545 */ 546 mtx_lock(&audit_mtx); 547 if (!audit_override && (audit_suspended || !audit_enabled)) { 548 audit_pre_q_len--; 549 mtx_unlock(&audit_mtx); 550 audit_free(ar); 551 return; 552 } 553 554 /* 555 * Constrain the number of committed audit records based on the 556 * configurable parameter. 557 */ 558 while (audit_q_len >= audit_qctrl.aq_hiwater) 559 cv_wait(&audit_watermark_cv, &audit_mtx); 560 561 TAILQ_INSERT_TAIL(&audit_q, ar, k_q); 562 audit_q_len++; 563 audit_pre_q_len--; 564 cv_signal(&audit_worker_cv); 565 mtx_unlock(&audit_mtx); 566} 567 568/* 569 * audit_syscall_enter() is called on entry to each system call. It is 570 * responsible for deciding whether or not to audit the call (preselection), 571 * and if so, allocating a per-thread audit record. audit_new() will fill in 572 * basic thread/credential properties. 573 */ 574void 575audit_syscall_enter(unsigned int code, proc_t proc, struct uthread *uthread) 576{ 577 struct au_mask *aumask; 578 au_class_t class; 579 au_event_t event; 580 au_id_t auid; 581 kauth_cred_t cred; 582 583 /* 584 * In FreeBSD, each ABI has its own system call table, and hence 585 * mapping of system call codes to audit events. Convert the code to 586 * an audit event identifier using the process system call table 587 * reference. In Darwin, there's only one, so we use the global 588 * symbol for the system call table. No audit record is generated 589 * for bad system calls, as no operation has been performed. 590 * 591 * In Mac OS X, the audit events are stored in a table seperate from 592 * the syscall table(s). This table is generated by makesyscalls.sh 593 * from syscalls.master and stored in audit_kevents.c. 594 */ 595 if (code > NUM_SYSENT) 596 return; 597 event = sys_au_event[code]; 598 if (event == AUE_NULL) 599 return; 600 601 KASSERT(uthread->uu_ar == NULL, 602 ("audit_syscall_enter: uthread->uu_ar != NULL")); 603 604 /* 605 * Check which audit mask to use; either the kernel non-attributable 606 * event mask or the process audit mask. 607 */ 608 cred = kauth_cred_proc_ref(proc); 609 auid = cred->cr_audit.as_aia_p->ai_auid; 610 if (auid == AU_DEFAUDITID) 611 aumask = &audit_nae_mask; 612 else 613 aumask = &cred->cr_audit.as_mask; 614 615 /* 616 * Allocate an audit record, if preselection allows it, and store in 617 * the thread for later use. 618 */ 619 class = au_event_class(event); 620#if CONFIG_MACF 621 /* 622 * Note: audit_mac_syscall_enter() may call audit_new() and allocate 623 * memory for the audit record (uu_ar). 624 */ 625 if (audit_mac_syscall_enter(code, proc, uthread, cred, event) == 0) 626 goto out; 627#endif 628 if (au_preselect(event, class, aumask, AU_PRS_BOTH)) { 629 /* 630 * If we're out of space and need to suspend unprivileged 631 * processes, do that here rather than trying to allocate 632 * another audit record. 633 * 634 * Note: we might wish to be able to continue here in the 635 * future, if the system recovers. That should be possible 636 * by means of checking the condition in a loop around 637 * cv_wait(). It might be desirable to reevaluate whether an 638 * audit record is still required for this event by 639 * re-calling au_preselect(). 640 */ 641 if (audit_in_failure && 642 suser(cred, &proc->p_acflag) != 0) { 643 cv_wait(&audit_fail_cv, &audit_mtx); 644 panic("audit_failing_stop: thread continued"); 645 } 646 if (uthread->uu_ar == NULL) 647 uthread->uu_ar = audit_new(event, proc, uthread); 648 } else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) { 649 if (uthread->uu_ar == NULL) 650 uthread->uu_ar = audit_new(event, proc, uthread); 651 } 652 653out: 654 kauth_cred_unref(&cred); 655} 656 657/* 658 * audit_syscall_exit() is called from the return of every system call, or in 659 * the event of exit1(), during the execution of exit1(). It is responsible 660 * for committing the audit record, if any, along with return condition. 661 * 662 * Note: The audit_syscall_exit() parameter list was modified to support 663 * mac_audit_check_postselect(), which requires the syscall number. 664 */ 665#if CONFIG_MACF 666void 667audit_syscall_exit(unsigned int code, int error, __unused proc_t proc, 668 struct uthread *uthread) 669#else 670void 671audit_syscall_exit(int error, __unsed proc_t proc, struct uthread *uthread) 672#endif 673{ 674 int retval; 675 676 /* 677 * Commit the audit record as desired; once we pass the record into 678 * audit_commit(), the memory is owned by the audit subsystem. The 679 * return value from the system call is stored on the user thread. 680 * If there was an error, the return value is set to -1, imitating 681 * the behavior of the cerror routine. 682 */ 683 if (error) 684 retval = -1; 685 else 686 retval = uthread->uu_rval[0]; 687 688#if CONFIG_MACF 689 if (audit_mac_syscall_exit(code, uthread, error, retval) != 0) 690 goto out; 691#endif 692 audit_commit(uthread->uu_ar, error, retval); 693 694out: 695 uthread->uu_ar = NULL; 696} 697 698/* 699 * Calls to set up and tear down audit structures used during Mach system 700 * calls. 701 */ 702void 703audit_mach_syscall_enter(unsigned short event) 704{ 705 struct uthread *uthread; 706 proc_t proc; 707 struct au_mask *aumask; 708 kauth_cred_t cred; 709 au_class_t class; 710 au_id_t auid; 711 712 if (event == AUE_NULL) 713 return; 714 715 uthread = curthread(); 716 if (uthread == NULL) 717 return; 718 719 proc = current_proc(); 720 if (proc == NULL) 721 return; 722 723 KASSERT(uthread->uu_ar == NULL, 724 ("audit_mach_syscall_enter: uthread->uu_ar != NULL")); 725 726 cred = kauth_cred_proc_ref(proc); 727 auid = cred->cr_audit.as_aia_p->ai_auid; 728 729 /* 730 * Check which audit mask to use; either the kernel non-attributable 731 * event mask or the process audit mask. 732 */ 733 if (auid == AU_DEFAUDITID) 734 aumask = &audit_nae_mask; 735 else 736 aumask = &cred->cr_audit.as_mask; 737 738 /* 739 * Allocate an audit record, if desired, and store in the BSD thread 740 * for later use. 741 */ 742 class = au_event_class(event); 743 if (au_preselect(event, class, aumask, AU_PRS_BOTH)) 744 uthread->uu_ar = audit_new(event, proc, uthread); 745 else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) 746 uthread->uu_ar = audit_new(event, proc, uthread); 747 else 748 uthread->uu_ar = NULL; 749 750 kauth_cred_unref(&cred); 751} 752 753void 754audit_mach_syscall_exit(int retval, struct uthread *uthread) 755{ 756 /* 757 * The error code from Mach system calls is the same as the 758 * return value 759 */ 760 /* XXX Is the above statement always true? */ 761 audit_commit(uthread->uu_ar, retval, retval); 762 uthread->uu_ar = NULL; 763} 764 765/* 766 * kau_will_audit can be used by a security policy to determine 767 * if an audit record will be stored, reducing wasted memory allocation 768 * and string handling. 769 */ 770int 771kau_will_audit(void) 772{ 773 774 return (audit_enabled && currecord() != NULL); 775} 776 777void 778audit_proc_coredump(proc_t proc, char *path, int errcode) 779{ 780 struct kaudit_record *ar; 781 struct au_mask *aumask; 782 au_class_t class; 783 int ret, sorf; 784 char **pathp; 785 au_id_t auid; 786 kauth_cred_t my_cred; 787 struct uthread *uthread; 788 789 ret = 0; 790 791 /* 792 * Make sure we are using the correct preselection mask. 793 */ 794 my_cred = kauth_cred_proc_ref(proc); 795 auid = my_cred->cr_audit.as_aia_p->ai_auid; 796 if (auid == AU_DEFAUDITID) 797 aumask = &audit_nae_mask; 798 else 799 aumask = &my_cred->cr_audit.as_mask; 800 kauth_cred_unref(&my_cred); 801 /* 802 * It's possible for coredump(9) generation to fail. Make sure that 803 * we handle this case correctly for preselection. 804 */ 805 if (errcode != 0) 806 sorf = AU_PRS_FAILURE; 807 else 808 sorf = AU_PRS_SUCCESS; 809 class = au_event_class(AUE_CORE); 810 if (au_preselect(AUE_CORE, class, aumask, sorf) == 0 && 811 audit_pipe_preselect(auid, AUE_CORE, class, sorf, 0) == 0) 812 return; 813 /* 814 * If we are interested in seeing this audit record, allocate it. 815 * Where possible coredump records should contain a pathname and arg32 816 * (signal) tokens. 817 */ 818 uthread = curthread(); 819 ar = audit_new(AUE_CORE, proc, uthread); 820 if (path != NULL) { 821 pathp = &ar->k_ar.ar_arg_upath1; 822 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); 823 if (audit_canon_path(vfs_context_cwd(vfs_context_current()), path, 824 *pathp)) 825 free(*pathp, M_AUDITPATH); 826 else 827 ARG_SET_VALID(ar, ARG_UPATH1); 828 } 829 ar->k_ar.ar_arg_signum = proc->p_sigacts->ps_sig; 830 ARG_SET_VALID(ar, ARG_SIGNUM); 831 if (errcode != 0) 832 ret = 1; 833 audit_commit(ar, errcode, ret); 834} 835#endif /* CONFIG_AUDIT */ 836