diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-03-19 17:34:00 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-03-19 17:34:00 +0000 |
commit | 9c0a4e82f3f7381e1fde26b4c69cfc31e480bd53 (patch) | |
tree | 4546d95e1fa0f362af8a9b34794af5a895124e33 /sys/security/audit/audit_worker.c | |
parent | 6163ee5a7b865b66b1dd7f437ade09ea314d0b68 (diff) | |
download | FreeBSD-src-9c0a4e82f3f7381e1fde26b4c69cfc31e480bd53.zip FreeBSD-src-9c0a4e82f3f7381e1fde26b4c69cfc31e480bd53.tar.gz |
Merge Perforce change 93581 from TrustedBSD audit3 branch:
Mega-style patch.
Obtained from: TrustedBSD Project
Diffstat (limited to 'sys/security/audit/audit_worker.c')
-rw-r--r-- | sys/security/audit/audit_worker.c | 149 |
1 files changed, 73 insertions, 76 deletions
diff --git a/sys/security/audit/audit_worker.c b/sys/security/audit/audit_worker.c index f975800..97ea66f 100644 --- a/sys/security/audit/audit_worker.c +++ b/sys/security/audit/audit_worker.c @@ -71,22 +71,22 @@ /* * Worker thread that will schedule disk I/O, etc. - */ + */ static struct proc *audit_thread; /* - * When an audit log is rotated, the actual rotation must be performed - * by the audit worker thread, as it may have outstanding writes on the - * current audit log. audit_replacement_vp holds the vnode replacing - * the current vnode. We can't let more than one replacement occur - * at a time, so if more than one thread requests a replacement, only - * one can have the replacement "in progress" at any given moment. If - * a thread tries to replace the audit vnode and discovers a replacement - * is already in progress (i.e., audit_replacement_flag != 0), then it - * will sleep on audit_replacement_cv waiting its turn to perform a - * replacement. When a replacement is completed, this cv is signalled - * by the worker thread so a waiting thread can start another replacement. - * We also store a credential to perform audit log write operations with. + * When an audit log is rotated, the actual rotation must be performed by the + * audit worker thread, as it may have outstanding writes on the current + * audit log. audit_replacement_vp holds the vnode replacing the current + * vnode. We can't let more than one replacement occur at a time, so if more + * than one thread requests a replacement, only one can have the replacement + * "in progress" at any given moment. If a thread tries to replace the audit + * vnode and discovers a replacement is already in progress (i.e., + * audit_replacement_flag != 0), then it will sleep on audit_replacement_cv + * waiting its turn to perform a replacement. When a replacement is + * completed, this cv is signalled by the worker thread so a waiting thread + * can start another replacement. We also store a credential to perform + * audit log write operations with. * * The current credential and vnode are thread-local to audit_worker. */ @@ -103,13 +103,13 @@ static int audit_file_rotate_wait; /* * XXXAUDIT: Should adjust comments below to make it clear that we get to - * this point only if we believe we have storage, so not having space here - * is a violation of invariants derived from administrative procedures. - * I.e., someone else has written to the audit partition, leaving less space - * than we accounted for. + * this point only if we believe we have storage, so not having space here is + * a violation of invariants derived from administrative procedures. I.e., + * someone else has written to the audit partition, leaving less space than + * we accounted for. */ static int -audit_record_write(struct vnode *vp, struct kaudit_record *ar, +audit_record_write(struct vnode *vp, struct kaudit_record *ar, struct ucred *cred, struct thread *td) { int ret; @@ -122,10 +122,10 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, vfslocked = VFS_LOCK_GIANT(vp->v_mount); /* - * First, gather statistics on the audit log file and file system - * so that we know how we're doing on space. In both cases, - * if we're unable to perform the operation, we drop the record - * and return. However, this is arguably an assertion failure. + * First, gather statistics on the audit log file and file system so + * that we know how we're doing on space. In both cases, if we're + * unable to perform the operation, we drop the record and return. + * However, this is arguably an assertion failure. * XXX Need a FreeBSD equivalent. */ ret = VFS_STATFS(vp->v_mount, mnt_stat, td); @@ -139,23 +139,24 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, goto out; /* update the global stats struct */ - audit_fstat.af_currsz = vattr.va_size; + audit_fstat.af_currsz = vattr.va_size; /* * XXX Need to decide what to do if the trigger to the audit daemon * fails. */ - /* + /* * If we fall below minimum free blocks (hard limit), tell the audit * daemon to force a rotation off of the file system. We also stop - * writing, which means this audit record is probably lost. - * If we fall below the minimum percent free blocks (soft limit), - * then kindly suggest to the audit daemon to do something. + * writing, which means this audit record is probably lost. If we + * fall below the minimum percent free blocks (soft limit), then + * kindly suggest to the audit daemon to do something. */ if (mnt_stat->f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) { (void)send_trigger(AUDIT_TRIGGER_NO_SPACE); - /* Hopefully userspace did something about all the previous + /* + * Hopefully userspace did something about all the previous * triggers that were sent prior to this critical condition. * If fail-stop is set, then we're done; goodnight Gracie. */ @@ -167,26 +168,27 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, goto out; } } else - /* - * Send a message to the audit daemon that disk space - * is getting low. + /* + * Send a message to the audit daemon that disk space is + * getting low. * * XXXAUDIT: Check math and block size calculation here. */ if (audit_qctrl.aq_minfree != 0) { - temp = mnt_stat->f_blocks / (100 / + temp = mnt_stat->f_blocks / (100 / audit_qctrl.aq_minfree); if (mnt_stat->f_bfree < temp) (void)send_trigger(AUDIT_TRIGGER_LOW_SPACE); } - /* Check if the current log file is full; if so, call for - * a log rotate. This is not an exact comparison; we may - * write some records over the limit. If that's not - * acceptable, then add a fudge factor here. + /* + * Check if the current log file is full; if so, call for a log + * rotate. This is not an exact comparison; we may write some records + * over the limit. If that's not acceptable, then add a fudge factor + * here. */ if ((audit_fstat.af_filesz != 0) && - (audit_file_rotate_wait == 0) && + (audit_file_rotate_wait == 0) && (vattr.va_size >= audit_fstat.af_filesz)) { audit_file_rotate_wait = 1; (void)send_trigger(AUDIT_TRIGGER_OPEN_NEW); @@ -194,15 +196,14 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, /* * If the estimated amount of audit data in the audit event queue - * (plus records allocated but not yet queued) has reached the - * amount of free space on the disk, then we need to go into an - * audit fail stop state, in which we do not permit the - * allocation/committing of any new audit records. We continue to - * process packets but don't allow any activities that might - * generate new records. In the future, we might want to detect - * when space is available again and allow operation to continue, - * but this behavior is sufficient to meet fail stop requirements - * in CAPP. + * (plus records allocated but not yet queued) has reached the amount + * of free space on the disk, then we need to go into an audit fail + * stop state, in which we do not permit the allocation/committing of + * any new audit records. We continue to process packets but don't + * allow any activities that might generate new records. In the + * future, we might want to detect when space is available again and + * allow operation to continue, but this behavior is sufficient to + * meet fail stop requirements in CAPP. */ if (audit_fail_stop && (unsigned long) @@ -213,15 +214,14 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, audit_in_failure = 1; } - /* + /* * If there is a user audit record attached to the kernel record, * then write the user record. - */ - /* XXX Need to decide a few things here: IF the user audit - * record is written, but the write of the kernel record fails, - * what to do? Should the kernel record come before or after the - * user record? For now, we write the user record first, and - * we ignore errors. + * + * XXX Need to decide a few things here: IF the user audit record is + * written, but the write of the kernel record fails, what to do? + * Should the kernel record come before or after the user record? + * For now, we write the user record first, and we ignore errors. */ if (ar->k_ar_commit & AR_COMMIT_USER) { /* @@ -233,15 +233,15 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, * And to disk. */ ret = vn_rdwr(UIO_WRITE, vp, (void *)ar->k_udata, ar->k_ulen, - (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, - NULL, td); + (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, + NULL, td); if (ret) goto out; } - /* - * Convert the internal kernel record to BSM format and write it - * out if everything's OK. + /* + * Convert the internal kernel record to BSM format and write it out + * if everything's OK. */ if (!(ar->k_ar_commit & AR_COMMIT_KERNEL)) { ret = 0; @@ -259,8 +259,8 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, } /* - * XXX: We drop the record on BSM conversion failure, but really - * this is an assertion failure. + * XXX: We drop the record on BSM conversion failure, but really this + * is an assertion failure. */ if (ret == BSM_FAILURE) { AUDIT_PRINTF(("BSM conversion failure\n")); @@ -272,28 +272,25 @@ audit_record_write(struct vnode *vp, struct kaudit_record *ar, * Try submitting the record to any active audit pipes. */ audit_pipe_submit((void *)bsm->data, bsm->len); - + /* - * XXX - * We should break the write functionality away from the BSM record - * generation and have the BSM generation done before this function - * is called. This function will then take the BSM record as a - * parameter. + * XXX We should break the write functionality away from the BSM + * record generation and have the BSM generation done before this + * function is called. This function will then take the BSM record as + * a parameter. */ - ret = (vn_rdwr(UIO_WRITE, vp, (void *)bsm->data, bsm->len, - (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, NULL, td)); - + ret = (vn_rdwr(UIO_WRITE, vp, (void *)bsm->data, bsm->len, (off_t)0, + UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, NULL, td)); kau_free(bsm); out: /* - * When we're done processing the current record, we have to - * check to see if we're in a failure mode, and if so, whether - * this was the last record left to be drained. If we're done - * draining, then we fsync the vnode and panic. + * When we're done processing the current record, we have to check to + * see if we're in a failure mode, and if so, whether this was the + * last record left to be drained. If we're done draining, then we + * fsync the vnode and panic. */ - if (audit_in_failure && - audit_q_len == 0 && audit_pre_q_len == 0) { + if (audit_in_failure && audit_q_len == 0 && audit_pre_q_len == 0) { VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, td); (void)VOP_FSYNC(vp, MNT_WAIT, td); VOP_UNLOCK(vp, 0, td); @@ -469,7 +466,7 @@ audit_worker(void *arg) while ((ar = TAILQ_FIRST(&ar_worklist))) { TAILQ_REMOVE(&ar_worklist, ar, k_q); if (audit_vp != NULL) { - error = audit_record_write(audit_vp, ar, + error = audit_record_write(audit_vp, ar, audit_cred, audit_td); if (error && audit_panic_on_write_fail) panic("audit_worker: write error %d\n", |