audit.c (170182) | audit.c (170196) |
---|---|
1/* 2 * Copyright (c) 1999-2005 Apple Computer, Inc. 3 * Copyright (c) 2006 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: --- 13 unchanged lines hidden (view full) --- 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 * | 1/* 2 * Copyright (c) 1999-2005 Apple Computer, Inc. 3 * Copyright (c) 2006 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: --- 13 unchanged lines hidden (view full) --- 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 * $FreeBSD: head/sys/security/audit/audit.c 170182 2007-06-01 13:53:37Z rwatson $ | 30 * $FreeBSD: head/sys/security/audit/audit.c 170196 2007-06-01 21:58:59Z rwatson $ |
31 */ 32 33#include <sys/param.h> 34#include <sys/condvar.h> 35#include <sys/conf.h> 36#include <sys/file.h> 37#include <sys/filedesc.h> 38#include <sys/fcntl.h> --- 33 unchanged lines hidden (view full) --- 72 73static uma_zone_t audit_record_zone; 74static MALLOC_DEFINE(M_AUDITPROC, "audit_proc", "Audit process storage"); 75MALLOC_DEFINE(M_AUDITDATA, "audit_data", "Audit data storage"); 76MALLOC_DEFINE(M_AUDITPATH, "audit_path", "Audit path storage"); 77MALLOC_DEFINE(M_AUDITTEXT, "audit_text", "Audit text storage"); 78 79/* | 31 */ 32 33#include <sys/param.h> 34#include <sys/condvar.h> 35#include <sys/conf.h> 36#include <sys/file.h> 37#include <sys/filedesc.h> 38#include <sys/fcntl.h> --- 33 unchanged lines hidden (view full) --- 72 73static uma_zone_t audit_record_zone; 74static MALLOC_DEFINE(M_AUDITPROC, "audit_proc", "Audit process storage"); 75MALLOC_DEFINE(M_AUDITDATA, "audit_data", "Audit data storage"); 76MALLOC_DEFINE(M_AUDITPATH, "audit_path", "Audit path storage"); 77MALLOC_DEFINE(M_AUDITTEXT, "audit_text", "Audit text storage"); 78 79/* |
80 * Audit control settings that are set/read by system calls and are 81 * hence non-static. 82 */ 83/* | 80 * Audit control settings that are set/read by system calls and are hence 81 * non-static. 82 * |
84 * Define the audit control flags. 85 */ 86int audit_enabled; 87int audit_suspended; 88 89/* 90 * Flags controlling behavior in low storage situations. Should we panic if 91 * a write fails? Should we fail stop if we're out of disk space? --- 20 unchanged lines hidden (view full) --- 112 113/* 114 * Mutex to protect global variables shared between various threads and 115 * processes. 116 */ 117struct mtx audit_mtx; 118 119/* | 83 * Define the audit control flags. 84 */ 85int audit_enabled; 86int audit_suspended; 87 88/* 89 * Flags controlling behavior in low storage situations. Should we panic if 90 * a write fails? Should we fail stop if we're out of disk space? --- 20 unchanged lines hidden (view full) --- 111 112/* 113 * Mutex to protect global variables shared between various threads and 114 * processes. 115 */ 116struct mtx audit_mtx; 117 118/* |
120 * Queue of audit records ready for delivery to disk. We insert new 121 * records at the tail, and remove records from the head. Also, 122 * a count of the number of records used for checking queue depth. 123 * In addition, a counter of records that we have allocated but are 124 * not yet in the queue, which is needed to estimate the total 125 * size of the combined set of records outstanding in the system. | 119 * Queue of audit records ready for delivery to disk. We insert new records 120 * at the tail, and remove records from the head. Also, a count of the 121 * number of records used for checking queue depth. In addition, a counter 122 * of records that we have allocated but are not yet in the queue, which is 123 * needed to estimate the total size of the combined set of records 124 * outstanding in the system. |
126 */ 127struct kaudit_queue audit_q; 128int audit_q_len; 129int audit_pre_q_len; 130 131/* 132 * Audit queue control settings (minimum free, low/high water marks, etc.) 133 */ 134struct au_qctrl audit_qctrl; 135 136/* | 125 */ 126struct kaudit_queue audit_q; 127int audit_q_len; 128int audit_pre_q_len; 129 130/* 131 * Audit queue control settings (minimum free, low/high water marks, etc.) 132 */ 133struct au_qctrl audit_qctrl; 134 135/* |
137 * Condition variable to signal to the worker that it has work to do: 138 * either new records are in the queue, or a log replacement is taking 139 * place. | 136 * Condition variable to signal to the worker that it has work to do: either 137 * new records are in the queue, or a log replacement is taking place. |
140 */ 141struct cv audit_worker_cv; 142 143/* 144 * Condition variable to flag when crossing the low watermark, meaning that 145 * threads blocked due to hitting the high watermark can wake up and continue 146 * to commit records. 147 */ 148struct cv audit_watermark_cv; 149 150/* 151 * Condition variable for auditing threads wait on when in fail-stop mode. | 138 */ 139struct cv audit_worker_cv; 140 141/* 142 * Condition variable to flag when crossing the low watermark, meaning that 143 * threads blocked due to hitting the high watermark can wake up and continue 144 * to commit records. 145 */ 146struct cv audit_watermark_cv; 147 148/* 149 * Condition variable for auditing threads wait on when in fail-stop mode. |
152 * Threads wait on this CV forever (and ever), never seeing the light of 153 * day again. | 150 * Threads wait on this CV forever (and ever), never seeing the light of day 151 * again. |
154 */ 155static struct cv audit_fail_cv; 156 157/* 158 * Construct an audit record for the passed thread. 159 */ 160static int 161audit_record_ctor(void *mem, int size, void *arg, int flags) --- 18 unchanged lines hidden (view full) --- 180 ar->k_ar.ar_subj_egid = td->td_ucred->cr_groups[0]; 181 PROC_LOCK(td->td_proc); 182 ar->k_ar.ar_subj_auid = td->td_proc->p_au->ai_auid; 183 ar->k_ar.ar_subj_asid = td->td_proc->p_au->ai_asid; 184 ar->k_ar.ar_subj_pid = td->td_proc->p_pid; 185 ar->k_ar.ar_subj_amask = td->td_proc->p_au->ai_mask; 186 ar->k_ar.ar_subj_term_addr = td->td_proc->p_au->ai_termid; 187 PROC_UNLOCK(td->td_proc); | 152 */ 153static struct cv audit_fail_cv; 154 155/* 156 * Construct an audit record for the passed thread. 157 */ 158static int 159audit_record_ctor(void *mem, int size, void *arg, int flags) --- 18 unchanged lines hidden (view full) --- 178 ar->k_ar.ar_subj_egid = td->td_ucred->cr_groups[0]; 179 PROC_LOCK(td->td_proc); 180 ar->k_ar.ar_subj_auid = td->td_proc->p_au->ai_auid; 181 ar->k_ar.ar_subj_asid = td->td_proc->p_au->ai_asid; 182 ar->k_ar.ar_subj_pid = td->td_proc->p_pid; 183 ar->k_ar.ar_subj_amask = td->td_proc->p_au->ai_mask; 184 ar->k_ar.ar_subj_term_addr = td->td_proc->p_au->ai_termid; 185 PROC_UNLOCK(td->td_proc); |
188 | |
189 return (0); 190} 191 192static void 193audit_record_dtor(void *mem, int size, void *arg) 194{ 195 struct kaudit_record *ar; 196 --- 27 unchanged lines hidden (view full) --- 224 audit_enabled = 0; 225 audit_suspended = 0; 226 audit_panic_on_write_fail = 0; 227 audit_fail_stop = 0; 228 audit_in_failure = 0; 229 audit_argv = 0; 230 audit_arge = 0; 231 | 186 return (0); 187} 188 189static void 190audit_record_dtor(void *mem, int size, void *arg) 191{ 192 struct kaudit_record *ar; 193 --- 27 unchanged lines hidden (view full) --- 221 audit_enabled = 0; 222 audit_suspended = 0; 223 audit_panic_on_write_fail = 0; 224 audit_fail_stop = 0; 225 audit_in_failure = 0; 226 audit_argv = 0; 227 audit_arge = 0; 228 |
232 audit_fstat.af_filesz = 0; /* '0' means unset, unbounded */ | 229 audit_fstat.af_filesz = 0; /* '0' means unset, unbounded. */ |
233 audit_fstat.af_currsz = 0; 234 audit_nae_mask.am_success = AU_NULL; 235 audit_nae_mask.am_failure = AU_NULL; 236 237 TAILQ_INIT(&audit_q); 238 audit_q_len = 0; 239 audit_pre_q_len = 0; 240 audit_qctrl.aq_hiwater = AQ_HIWATER; --- 97 unchanged lines hidden (view full) --- 338 au_id_t auid; 339 int sorf; 340 struct au_mask *aumask; 341 342 if (ar == NULL) 343 return; 344 345 /* | 230 audit_fstat.af_currsz = 0; 231 audit_nae_mask.am_success = AU_NULL; 232 audit_nae_mask.am_failure = AU_NULL; 233 234 TAILQ_INIT(&audit_q); 235 audit_q_len = 0; 236 audit_pre_q_len = 0; 237 audit_qctrl.aq_hiwater = AQ_HIWATER; --- 97 unchanged lines hidden (view full) --- 335 au_id_t auid; 336 int sorf; 337 struct au_mask *aumask; 338 339 if (ar == NULL) 340 return; 341 342 /* |
346 * Decide whether to commit the audit record by checking the 347 * error value from the system call and using the appropriate 348 * audit mask. | 343 * Decide whether to commit the audit record by checking the error 344 * value from the system call and using the appropriate audit mask. |
349 * 350 * XXXAUDIT: Synchronize access to audit_nae_mask? 351 */ 352 if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) 353 aumask = &audit_nae_mask; 354 else 355 aumask = &ar->k_ar.ar_subj_amask; 356 357 if (error) 358 sorf = AU_PRS_FAILURE; 359 else 360 sorf = AU_PRS_SUCCESS; 361 362 switch(ar->k_ar.ar_event) { | 345 * 346 * XXXAUDIT: Synchronize access to audit_nae_mask? 347 */ 348 if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) 349 aumask = &audit_nae_mask; 350 else 351 aumask = &ar->k_ar.ar_subj_amask; 352 353 if (error) 354 sorf = AU_PRS_FAILURE; 355 else 356 sorf = AU_PRS_SUCCESS; 357 358 switch(ar->k_ar.ar_event) { |
363 | |
364 case AUE_OPEN_RWTC: | 359 case AUE_OPEN_RWTC: |
365 /* The open syscall always writes a AUE_OPEN_RWTC event; change 366 * it to the proper type of event based on the flags and the 367 * error value. | 360 /* 361 * The open syscall always writes a AUE_OPEN_RWTC event; 362 * change it to the proper type of event based on the flags 363 * and the error value. |
368 */ 369 ar->k_ar.ar_event = flags_and_error_to_openevent( 370 ar->k_ar.ar_arg_fflags, error); 371 break; 372 373 case AUE_SYSCTL: 374 ar->k_ar.ar_event = ctlname_to_sysctlevent( 375 ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); --- 23 unchanged lines hidden (view full) --- 399 audit_free(ar); 400 return; 401 } 402 403 ar->k_ar.ar_errno = error; 404 ar->k_ar.ar_retval = retval; 405 406 /* | 364 */ 365 ar->k_ar.ar_event = flags_and_error_to_openevent( 366 ar->k_ar.ar_arg_fflags, error); 367 break; 368 369 case AUE_SYSCTL: 370 ar->k_ar.ar_event = ctlname_to_sysctlevent( 371 ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); --- 23 unchanged lines hidden (view full) --- 395 audit_free(ar); 396 return; 397 } 398 399 ar->k_ar.ar_errno = error; 400 ar->k_ar.ar_retval = retval; 401 402 /* |
407 * We might want to do some system-wide post-filtering 408 * here at some point. | 403 * We might want to do some system-wide post-filtering here at some 404 * point. |
409 */ 410 411 /* 412 * Timestamp system call end. 413 */ 414 nanotime(&ar->k_ar.ar_endtime); 415 | 405 */ 406 407 /* 408 * Timestamp system call end. 409 */ 410 nanotime(&ar->k_ar.ar_endtime); 411 |
416 mtx_lock(&audit_mtx); 417 | |
418 /* 419 * Note: it could be that some records initiated while audit was 420 * enabled should still be committed? 421 */ | 412 /* 413 * Note: it could be that some records initiated while audit was 414 * enabled should still be committed? 415 */ |
416 mtx_lock(&audit_mtx); |
|
422 if (audit_suspended || !audit_enabled) { 423 audit_pre_q_len--; 424 mtx_unlock(&audit_mtx); 425 audit_free(ar); 426 return; 427 } 428 429 /* --- 47 unchanged lines hidden (view full) --- 477 */ 478 auid = td->td_proc->p_au->ai_auid; 479 if (auid == AU_DEFAUDITID) 480 aumask = &audit_nae_mask; 481 else 482 aumask = &td->td_proc->p_au->ai_mask; 483 484 /* | 417 if (audit_suspended || !audit_enabled) { 418 audit_pre_q_len--; 419 mtx_unlock(&audit_mtx); 420 audit_free(ar); 421 return; 422 } 423 424 /* --- 47 unchanged lines hidden (view full) --- 472 */ 473 auid = td->td_proc->p_au->ai_auid; 474 if (auid == AU_DEFAUDITID) 475 aumask = &audit_nae_mask; 476 else 477 aumask = &td->td_proc->p_au->ai_mask; 478 479 /* |
485 * Allocate an audit record, if preselection allows it, and store 486 * in the thread for later use. | 480 * Allocate an audit record, if preselection allows it, and store in 481 * the thread for later use. |
487 */ 488 class = au_event_class(event); 489 if (au_preselect(event, class, aumask, AU_PRS_BOTH)) { 490 /* 491 * If we're out of space and need to suspend unprivileged 492 * processes, do that here rather than trying to allocate 493 * another audit record. 494 * --- 22 unchanged lines hidden (view full) --- 517 * for committing the audit record, if any, along with return condition. 518 */ 519void 520audit_syscall_exit(int error, struct thread *td) 521{ 522 int retval; 523 524 /* | 482 */ 483 class = au_event_class(event); 484 if (au_preselect(event, class, aumask, AU_PRS_BOTH)) { 485 /* 486 * If we're out of space and need to suspend unprivileged 487 * processes, do that here rather than trying to allocate 488 * another audit record. 489 * --- 22 unchanged lines hidden (view full) --- 512 * for committing the audit record, if any, along with return condition. 513 */ 514void 515audit_syscall_exit(int error, struct thread *td) 516{ 517 int retval; 518 519 /* |
525 * Commit the audit record as desired; once we pass the record 526 * into audit_commit(), the memory is owned by the audit 527 * subsystem. 528 * The return value from the system call is stored on the user 529 * thread. If there was an error, the return value is set to -1, 530 * imitating the behavior of the cerror routine. | 520 * Commit the audit record as desired; once we pass the record into 521 * audit_commit(), the memory is owned by the audit subsystem. The 522 * return value from the system call is stored on the user thread. 523 * If there was an error, the return value is set to -1, imitating 524 * the behavior of the cerror routine. |
531 */ 532 if (error) 533 retval = -1; 534 else 535 retval = td->td_retval[0]; 536 537 audit_commit(td->td_ar, error, retval); 538 td->td_ar = NULL; --- 39 unchanged lines hidden (view full) --- 578 * session ID, etc. 579 */ 580void 581audit_proc_kproc0(struct proc *p) 582{ 583 584 KASSERT(p->p_au != NULL, ("audit_proc_kproc0: p->p_au == NULL (%d)", 585 p->p_pid)); | 525 */ 526 if (error) 527 retval = -1; 528 else 529 retval = td->td_retval[0]; 530 531 audit_commit(td->td_ar, error, retval); 532 td->td_ar = NULL; --- 39 unchanged lines hidden (view full) --- 572 * session ID, etc. 573 */ 574void 575audit_proc_kproc0(struct proc *p) 576{ 577 578 KASSERT(p->p_au != NULL, ("audit_proc_kproc0: p->p_au == NULL (%d)", 579 p->p_pid)); |
580 |
|
586 bzero(p->p_au, sizeof(*(p)->p_au)); 587} 588 589void 590audit_proc_init(struct proc *p) 591{ 592 593 KASSERT(p->p_au != NULL, ("audit_proc_init: p->p_au == NULL (%d)", 594 p->p_pid)); | 581 bzero(p->p_au, sizeof(*(p)->p_au)); 582} 583 584void 585audit_proc_init(struct proc *p) 586{ 587 588 KASSERT(p->p_au != NULL, ("audit_proc_init: p->p_au == NULL (%d)", 589 p->p_pid)); |
590 |
|
595 bzero(p->p_au, sizeof(*(p)->p_au)); 596 p->p_au->ai_auid = AU_DEFAUDITID; 597} 598 599/* | 591 bzero(p->p_au, sizeof(*(p)->p_au)); 592 p->p_au->ai_auid = AU_DEFAUDITID; 593} 594 595/* |
600 * Copy the audit info from the parent process to the child process when 601 * a fork takes place. | 596 * Copy the audit info from the parent process to the child process when a 597 * fork takes place. |
602 */ 603void 604audit_proc_fork(struct proc *parent, struct proc *child) 605{ 606 607 PROC_LOCK_ASSERT(parent, MA_OWNED); 608 PROC_LOCK_ASSERT(child, MA_OWNED); 609 KASSERT(parent->p_au != NULL, 610 ("audit_proc_fork: parent->p_au == NULL (%d)", parent->p_pid)); 611 KASSERT(child->p_au != NULL, 612 ("audit_proc_fork: child->p_au == NULL (%d)", child->p_pid)); | 598 */ 599void 600audit_proc_fork(struct proc *parent, struct proc *child) 601{ 602 603 PROC_LOCK_ASSERT(parent, MA_OWNED); 604 PROC_LOCK_ASSERT(child, MA_OWNED); 605 KASSERT(parent->p_au != NULL, 606 ("audit_proc_fork: parent->p_au == NULL (%d)", parent->p_pid)); 607 KASSERT(child->p_au != NULL, 608 ("audit_proc_fork: child->p_au == NULL (%d)", child->p_pid)); |
609 |
|
613 bcopy(parent->p_au, child->p_au, sizeof(*child->p_au)); 614} 615 616/* 617 * Free the auditing structure for the process. 618 */ 619void 620audit_proc_free(struct proc *p) 621{ 622 623 KASSERT(p->p_au != NULL, ("p->p_au == NULL (%d)", p->p_pid)); | 610 bcopy(parent->p_au, child->p_au, sizeof(*child->p_au)); 611} 612 613/* 614 * Free the auditing structure for the process. 615 */ 616void 617audit_proc_free(struct proc *p) 618{ 619 620 KASSERT(p->p_au != NULL, ("p->p_au == NULL (%d)", p->p_pid)); |
621 |
|
624 free(p->p_au, M_AUDITPROC); 625 p->p_au = NULL; 626} | 622 free(p->p_au, M_AUDITPROC); 623 p->p_au = NULL; 624} |