Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1999-2005 Apple Computer, Inc.
|
|
|
|
* Copyright (c) 2006 Robert N. M. Watson
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
|
|
|
* its contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
|
|
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
|
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* $FreeBSD$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/condvar.h>
|
|
|
|
#include <sys/conf.h>
|
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/filedesc.h>
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/kthread.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/mount.h>
|
|
|
|
#include <sys/namei.h>
|
|
|
|
#include <sys/proc.h>
|
|
|
|
#include <sys/queue.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/socketvar.h>
|
|
|
|
#include <sys/protosw.h>
|
|
|
|
#include <sys/domain.h>
|
|
|
|
#include <sys/sysproto.h>
|
|
|
|
#include <sys/sysent.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/ucred.h>
|
|
|
|
#include <sys/uio.h>
|
|
|
|
#include <sys/un.h>
|
|
|
|
#include <sys/unistd.h>
|
|
|
|
#include <sys/vnode.h>
|
|
|
|
|
|
|
|
#include <bsm/audit.h>
|
|
|
|
#include <bsm/audit_internal.h>
|
|
|
|
#include <bsm/audit_kevents.h>
|
|
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_pcb.h>
|
|
|
|
|
|
|
|
#include <security/audit/audit.h>
|
|
|
|
#include <security/audit/audit_private.h>
|
|
|
|
|
|
|
|
#include <vm/uma.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Worker thread that will schedule disk I/O, etc.
|
2006-03-19 17:34:00 +00:00
|
|
|
*/
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
static struct proc *audit_thread;
|
|
|
|
|
|
|
|
/*
|
2006-03-19 17:34:00 +00:00
|
|
|
* 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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*
|
|
|
|
* The current credential and vnode are thread-local to audit_worker.
|
|
|
|
*/
|
|
|
|
static struct cv audit_replacement_cv;
|
|
|
|
|
|
|
|
static int audit_replacement_flag;
|
|
|
|
static struct vnode *audit_replacement_vp;
|
|
|
|
static struct ucred *audit_replacement_cred;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Flags related to Kernel->user-space communication.
|
|
|
|
*/
|
|
|
|
static int audit_file_rotate_wait;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXXAUDIT: Should adjust comments below to make it clear that we get to
|
2006-03-19 17:34:00 +00:00
|
|
|
* 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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*/
|
|
|
|
static int
|
2006-06-05 13:50:02 +00:00
|
|
|
audit_record_write(struct vnode *vp, struct ucred *cred, struct thread *td,
|
|
|
|
void *data, size_t len)
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
long temp;
|
|
|
|
struct vattr vattr;
|
2006-06-06 08:43:27 +00:00
|
|
|
struct statfs *mnt_stat;
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
int vfslocked;
|
|
|
|
|
2006-06-05 13:50:02 +00:00
|
|
|
if (vp == NULL)
|
|
|
|
return (0);
|
|
|
|
|
2006-06-06 08:43:27 +00:00
|
|
|
mnt_stat = &vp->v_mount->mnt_stat;
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
|
|
|
|
|
|
|
|
/*
|
2006-03-19 17:34:00 +00:00
|
|
|
* 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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
* XXX Need a FreeBSD equivalent.
|
|
|
|
*/
|
|
|
|
ret = VFS_STATFS(vp->v_mount, mnt_stat, td);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
|
|
|
ret = VOP_GETATTR(vp, &vattr, cred, td);
|
|
|
|
VOP_UNLOCK(vp, 0, td);
|
|
|
|
if (ret)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* update the global stats struct */
|
2006-03-19 17:34:00 +00:00
|
|
|
audit_fstat.af_currsz = vattr.va_size;
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX Need to decide what to do if the trigger to the audit daemon
|
|
|
|
* fails.
|
|
|
|
*/
|
|
|
|
|
2006-03-19 17:34:00 +00:00
|
|
|
/*
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
* 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
|
2006-03-19 17:34:00 +00:00
|
|
|
* 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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*/
|
|
|
|
if (mnt_stat->f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) {
|
|
|
|
(void)send_trigger(AUDIT_TRIGGER_NO_SPACE);
|
2006-03-19 17:34:00 +00:00
|
|
|
/*
|
|
|
|
* Hopefully userspace did something about all the previous
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
* triggers that were sent prior to this critical condition.
|
|
|
|
* If fail-stop is set, then we're done; goodnight Gracie.
|
|
|
|
*/
|
|
|
|
if (audit_fail_stop)
|
|
|
|
panic("Audit log space exhausted and fail-stop set.");
|
|
|
|
else {
|
|
|
|
audit_suspended = 1;
|
|
|
|
ret = ENOSPC;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else
|
2006-03-19 17:34:00 +00:00
|
|
|
/*
|
|
|
|
* Send a message to the audit daemon that disk space is
|
|
|
|
* getting low.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*
|
|
|
|
* XXXAUDIT: Check math and block size calculation here.
|
|
|
|
*/
|
|
|
|
if (audit_qctrl.aq_minfree != 0) {
|
2006-03-19 17:34:00 +00:00
|
|
|
temp = mnt_stat->f_blocks / (100 /
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
audit_qctrl.aq_minfree);
|
|
|
|
if (mnt_stat->f_bfree < temp)
|
|
|
|
(void)send_trigger(AUDIT_TRIGGER_LOW_SPACE);
|
|
|
|
}
|
|
|
|
|
2006-03-19 17:34:00 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*/
|
|
|
|
if ((audit_fstat.af_filesz != 0) &&
|
2006-03-19 17:34:00 +00:00
|
|
|
(audit_file_rotate_wait == 0) &&
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
(vattr.va_size >= audit_fstat.af_filesz)) {
|
|
|
|
audit_file_rotate_wait = 1;
|
2006-09-21 07:27:02 +00:00
|
|
|
(void)send_trigger(AUDIT_TRIGGER_ROTATE_KERNEL);
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the estimated amount of audit data in the audit event queue
|
2006-03-19 17:34:00 +00:00
|
|
|
* (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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*/
|
|
|
|
if (audit_fail_stop &&
|
|
|
|
(unsigned long)
|
|
|
|
((audit_q_len + audit_pre_q_len + 1) * MAX_AUDIT_RECORD_SIZE) /
|
|
|
|
mnt_stat->f_bsize >= (unsigned long)(mnt_stat->f_bfree)) {
|
|
|
|
printf("audit_record_write: free space below size of audit "
|
|
|
|
"queue, failing stop\n");
|
|
|
|
audit_in_failure = 1;
|
|
|
|
}
|
|
|
|
|
2006-06-05 13:50:02 +00:00
|
|
|
ret = vn_rdwr(UIO_WRITE, vp, data, len, (off_t)0, UIO_SYSSPACE,
|
|
|
|
IO_APPEND|IO_UNIT, cred, NULL, NULL, td);
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
|
|
|
|
out:
|
|
|
|
/*
|
2006-03-19 17:34:00 +00:00
|
|
|
* 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.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*/
|
2006-03-19 17:34:00 +00:00
|
|
|
if (audit_in_failure && audit_q_len == 0 && audit_pre_q_len == 0) {
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
VOP_LOCK(vp, LK_DRAIN | LK_INTERLOCK, td);
|
|
|
|
(void)VOP_FSYNC(vp, MNT_WAIT, td);
|
|
|
|
VOP_UNLOCK(vp, 0, td);
|
|
|
|
panic("Audit store overflow; record queue drained.");
|
|
|
|
}
|
|
|
|
|
|
|
|
VFS_UNLOCK_GIANT(vfslocked);
|
|
|
|
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If an appropriate signal has been received rotate the audit log based on
|
|
|
|
* the global replacement variables. Signal consumers as needed that the
|
|
|
|
* rotation has taken place.
|
|
|
|
*
|
|
|
|
* XXXRW: The global variables and CVs used to signal the audit_worker to
|
|
|
|
* perform a rotation are essentially a message queue of depth 1. It would
|
|
|
|
* be much nicer to actually use a message queue.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
audit_worker_rotate(struct ucred **audit_credp, struct vnode **audit_vpp,
|
|
|
|
struct thread *audit_td)
|
|
|
|
{
|
|
|
|
int do_replacement_signal, vfslocked;
|
|
|
|
struct ucred *old_cred;
|
|
|
|
struct vnode *old_vp;
|
|
|
|
|
|
|
|
mtx_assert(&audit_mtx, MA_OWNED);
|
|
|
|
|
|
|
|
do_replacement_signal = 0;
|
|
|
|
while (audit_replacement_flag != 0) {
|
|
|
|
old_cred = *audit_credp;
|
|
|
|
old_vp = *audit_vpp;
|
|
|
|
*audit_credp = audit_replacement_cred;
|
|
|
|
*audit_vpp = audit_replacement_vp;
|
|
|
|
audit_replacement_cred = NULL;
|
|
|
|
audit_replacement_vp = NULL;
|
|
|
|
audit_replacement_flag = 0;
|
|
|
|
|
|
|
|
audit_enabled = (*audit_vpp != NULL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX: What to do about write failures here?
|
|
|
|
*/
|
|
|
|
if (old_vp != NULL) {
|
|
|
|
AUDIT_PRINTF(("Closing old audit file\n"));
|
|
|
|
mtx_unlock(&audit_mtx);
|
|
|
|
vfslocked = VFS_LOCK_GIANT(old_vp->v_mount);
|
|
|
|
vn_close(old_vp, AUDIT_CLOSE_FLAGS, old_cred,
|
|
|
|
audit_td);
|
|
|
|
VFS_UNLOCK_GIANT(vfslocked);
|
|
|
|
crfree(old_cred);
|
|
|
|
mtx_lock(&audit_mtx);
|
|
|
|
old_cred = NULL;
|
|
|
|
old_vp = NULL;
|
|
|
|
AUDIT_PRINTF(("Audit file closed\n"));
|
|
|
|
}
|
|
|
|
if (*audit_vpp != NULL) {
|
|
|
|
AUDIT_PRINTF(("Opening new audit file\n"));
|
|
|
|
}
|
|
|
|
do_replacement_signal = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Signal that replacement have occurred to wake up and
|
|
|
|
* start any other replacements started in parallel. We can
|
|
|
|
* continue about our business in the mean time. We
|
|
|
|
* broadcast so that both new replacements can be inserted,
|
|
|
|
* but also so that the source(s) of replacement can return
|
|
|
|
* successfully.
|
|
|
|
*/
|
|
|
|
if (do_replacement_signal)
|
|
|
|
cv_broadcast(&audit_replacement_cv);
|
|
|
|
}
|
|
|
|
|
2006-06-05 13:46:55 +00:00
|
|
|
/*
|
2006-06-05 13:50:02 +00:00
|
|
|
* Given a kernel audit record, process as required. Kernel audit records
|
|
|
|
* are converted to one, or possibly two, BSM records, depending on whether
|
|
|
|
* there is a user audit record present also. Kernel records need be
|
|
|
|
* converted to BSM before they can be written out. Both types will be
|
|
|
|
* written to disk, and audit pipes.
|
2006-06-05 13:46:55 +00:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
audit_worker_process_record(struct vnode *audit_vp, struct ucred *audit_cred,
|
|
|
|
struct thread *audit_td, struct kaudit_record *ar)
|
|
|
|
{
|
2006-06-05 13:50:02 +00:00
|
|
|
struct au_record *bsm;
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
au_class_t class;
|
|
|
|
au_event_t event;
|
2006-06-05 13:50:02 +00:00
|
|
|
int error, ret;
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
au_id_t auid;
|
|
|
|
int sorf;
|
2006-06-05 13:46:55 +00:00
|
|
|
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
if ((ar->k_ar_commit & AR_COMMIT_USER) &&
|
2006-09-17 17:52:57 +00:00
|
|
|
(ar->k_ar_commit & AR_PRESELECT_USER_TRAIL)) {
|
2006-06-05 13:50:02 +00:00
|
|
|
error = audit_record_write(audit_vp, audit_cred, audit_td,
|
|
|
|
ar->k_udata, ar->k_ulen);
|
|
|
|
if (error && audit_panic_on_write_fail)
|
2006-06-05 13:46:55 +00:00
|
|
|
panic("audit_worker: write error %d\n", error);
|
2006-06-05 13:50:02 +00:00
|
|
|
else if (error)
|
2006-06-05 13:46:55 +00:00
|
|
|
printf("audit_worker: write error %d\n", error);
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
}
|
2006-09-17 17:52:57 +00:00
|
|
|
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
if ((ar->k_ar_commit & AR_COMMIT_USER) &&
|
2006-09-17 17:52:57 +00:00
|
|
|
(ar->k_ar_commit & AR_PRESELECT_USER_PIPE))
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
audit_pipe_submit_user(ar->k_udata, ar->k_ulen);
|
|
|
|
|
2006-09-17 17:52:57 +00:00
|
|
|
if (!(ar->k_ar_commit & AR_COMMIT_KERNEL) ||
|
|
|
|
((ar->k_ar_commit & AR_PRESELECT_PIPE) == 0 &&
|
|
|
|
(ar->k_ar_commit & AR_PRESELECT_TRAIL) == 0))
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
auid = ar->k_ar.ar_subj_auid;
|
|
|
|
event = ar->k_ar.ar_event;
|
|
|
|
class = au_event_class(event);
|
|
|
|
if (ar->k_ar.ar_errno == 0)
|
|
|
|
sorf = AU_PRS_SUCCESS;
|
|
|
|
else
|
|
|
|
sorf = AU_PRS_FAILURE;
|
|
|
|
|
|
|
|
ret = kaudit_to_bsm(ar, &bsm);
|
|
|
|
switch (ret) {
|
|
|
|
case BSM_NOAUDIT:
|
|
|
|
return;
|
|
|
|
|
|
|
|
case BSM_FAILURE:
|
|
|
|
printf("audit_worker_process_record: BSM_FAILURE\n");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case BSM_SUCCESS:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
panic("kaudit_to_bsm returned %d", ret);
|
2006-06-05 13:50:02 +00:00
|
|
|
}
|
|
|
|
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
if (ar->k_ar_commit & AR_PRESELECT_TRAIL) {
|
|
|
|
error = audit_record_write(audit_vp, audit_cred,
|
|
|
|
audit_td, bsm->data, bsm->len);
|
|
|
|
if (error && audit_panic_on_write_fail)
|
|
|
|
panic("audit_worker: write error %d\n",
|
|
|
|
error);
|
|
|
|
else if (error)
|
|
|
|
printf("audit_worker: write error %d\n",
|
|
|
|
error);
|
2006-06-05 13:46:55 +00:00
|
|
|
}
|
2006-09-17 17:52:57 +00:00
|
|
|
|
Introduce support for per-audit pipe preselection independent from the
global audit trail configuration. This allows applications consuming
audit trails to specify parameters for which audit records are of
interest, including selecting records not required by the global trail.
Allowing application interest specification without changing the global
configuration allows intrusion detection systems to run without
interfering with global auditing or each other (if multiple are
present). To implement this:
- Kernel audit records now carry a flag to indicate whether they have
been selected by the global trail or by the audit pipe subsystem,
set during record commit, so that this information is available
after BSM conversion when delivering the BSM to the trail and audit
pipes in the audit worker thread asynchronously. Preselection by
either record target will cause the record to be kept.
- Similar changes to preselection when the audit record is created
when the system call is entering: consult both the global trail and
pipes.
- au_preselect() now accepts the class in order to avoid repeatedly
looking up the mask for each preselection test.
- Define a series of ioctls that allow applications to specify whether
they want to track the global trail, or program their own
preselection parameters: they may specify their own flags and naflags
masks, similar to the global masks of the same name, as well as a set
of per-auid masks. They also set a per-pipe mode specifying whether
they track the global trail, or user their own -- the door is left
open for future additional modes. A new ioctl is defined to allow a
user process to flush the current audit pipe queue, which can be used
after reprogramming pre-selection to make sure that only records of
interest are received in future reads.
- Audit pipe data structures are extended to hold the additional fields
necessary to support preselection. By default, audit pipes track the
global trail, so "praudit /dev/auditpipe" will track the global audit
trail even though praudit doesn't program the audit pipe selection
model.
- Comment about the complexities of potentially adding partial read
support to audit pipes.
By using a set of ioctls, applications can select which records are of
interest, and toggle the preselection mode.
Obtained from: TrustedBSD Project
2006-06-05 14:48:17 +00:00
|
|
|
if (ar->k_ar_commit & AR_PRESELECT_PIPE)
|
|
|
|
audit_pipe_submit(auid, event, class, sorf,
|
|
|
|
ar->k_ar_commit & AR_PRESELECT_TRAIL, bsm->data,
|
|
|
|
bsm->len);
|
|
|
|
kau_free(bsm);
|
2006-06-05 13:46:55 +00:00
|
|
|
}
|
|
|
|
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
/*
|
|
|
|
* The audit_worker thread is responsible for watching the event queue,
|
|
|
|
* dequeueing records, converting them to BSM format, and committing them to
|
|
|
|
* disk. In order to minimize lock thrashing, records are dequeued in sets
|
|
|
|
* to a thread-local work queue. In addition, the audit_work performs the
|
|
|
|
* actual exchange of audit log vnode pointer, as audit_vp is a thread-local
|
|
|
|
* variable.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
audit_worker(void *arg)
|
|
|
|
{
|
2006-06-05 13:45:05 +00:00
|
|
|
struct kaudit_queue ar_worklist;
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
struct kaudit_record *ar;
|
|
|
|
struct ucred *audit_cred;
|
|
|
|
struct thread *audit_td;
|
|
|
|
struct vnode *audit_vp;
|
2006-06-05 13:46:55 +00:00
|
|
|
int lowater_signal;
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
|
|
|
|
AUDIT_PRINTF(("audit_worker starting\n"));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These are thread-local variables requiring no synchronization.
|
|
|
|
*/
|
|
|
|
TAILQ_INIT(&ar_worklist);
|
|
|
|
audit_cred = NULL;
|
|
|
|
audit_td = curthread;
|
|
|
|
audit_vp = NULL;
|
|
|
|
|
|
|
|
mtx_lock(&audit_mtx);
|
|
|
|
while (1) {
|
|
|
|
mtx_assert(&audit_mtx, MA_OWNED);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Wait for record or rotation events.
|
|
|
|
*/
|
|
|
|
while (!audit_replacement_flag && TAILQ_EMPTY(&audit_q)) {
|
|
|
|
AUDIT_PRINTF(("audit_worker waiting\n"));
|
2006-06-05 13:43:57 +00:00
|
|
|
cv_wait(&audit_worker_cv, &audit_mtx);
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
AUDIT_PRINTF(("audit_worker woken up\n"));
|
|
|
|
AUDIT_PRINTF(("audit_worker: new vp = %p; value of "
|
|
|
|
"flag %d\n", audit_replacement_vp,
|
|
|
|
audit_replacement_flag));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First priority: replace the audit log target if requested.
|
|
|
|
*/
|
|
|
|
audit_worker_rotate(&audit_cred, &audit_vp, audit_td);
|
|
|
|
|
|
|
|
/*
|
2006-06-05 14:09:59 +00:00
|
|
|
* If there are records in the global audit record queue,
|
|
|
|
* transfer them to a thread-local queue and process them
|
|
|
|
* one by one. If we cross the low watermark threshold,
|
|
|
|
* signal any waiting processes that they may wake up and
|
|
|
|
* continue generating records.
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
*/
|
|
|
|
lowater_signal = 0;
|
|
|
|
while ((ar = TAILQ_FIRST(&audit_q))) {
|
|
|
|
TAILQ_REMOVE(&audit_q, ar, k_q);
|
|
|
|
audit_q_len--;
|
|
|
|
if (audit_q_len == audit_qctrl.aq_lowater)
|
|
|
|
lowater_signal++;
|
|
|
|
TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q);
|
|
|
|
}
|
|
|
|
if (lowater_signal)
|
2006-06-05 13:43:57 +00:00
|
|
|
cv_broadcast(&audit_watermark_cv);
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
|
|
|
|
mtx_unlock(&audit_mtx);
|
|
|
|
while ((ar = TAILQ_FIRST(&ar_worklist))) {
|
|
|
|
TAILQ_REMOVE(&ar_worklist, ar, k_q);
|
2006-06-05 13:46:55 +00:00
|
|
|
audit_worker_process_record(audit_vp, audit_cred,
|
|
|
|
audit_td, ar);
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
audit_free(ar);
|
|
|
|
}
|
|
|
|
mtx_lock(&audit_mtx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* audit_rotate_vnode() is called by a user or kernel thread to configure or
|
|
|
|
* de-configure auditing on a vnode. The arguments are the replacement
|
|
|
|
* credential and vnode to substitute for the current credential and vnode,
|
|
|
|
* if any. If either is set to NULL, both should be NULL, and this is used
|
|
|
|
* to indicate that audit is being disabled. The real work is done in the
|
|
|
|
* audit_worker thread, but audit_rotate_vnode() waits synchronously for that
|
|
|
|
* to complete.
|
|
|
|
*
|
|
|
|
* The vnode should be referenced and opened by the caller. The credential
|
|
|
|
* should be referenced. audit_rotate_vnode() will own both references as of
|
|
|
|
* this call, so the caller should not release either.
|
|
|
|
*
|
|
|
|
* XXXAUDIT: Review synchronize communication logic. Really, this is a
|
|
|
|
* message queue of depth 1.
|
|
|
|
*
|
|
|
|
* XXXAUDIT: Enhance the comments below to indicate that we are basically
|
|
|
|
* acquiring ownership of the communications queue, inserting our message,
|
|
|
|
* and waiting for an acknowledgement.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
audit_rotate_vnode(struct ucred *cred, struct vnode *vp)
|
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If other parallel log replacements have been requested, we wait
|
|
|
|
* until they've finished before continuing.
|
|
|
|
*/
|
|
|
|
mtx_lock(&audit_mtx);
|
|
|
|
while (audit_replacement_flag != 0) {
|
|
|
|
AUDIT_PRINTF(("audit_rotate_vnode: sleeping to wait for "
|
|
|
|
"flag\n"));
|
|
|
|
cv_wait(&audit_replacement_cv, &audit_mtx);
|
|
|
|
AUDIT_PRINTF(("audit_rotate_vnode: woken up (flag %d)\n",
|
|
|
|
audit_replacement_flag));
|
|
|
|
}
|
|
|
|
audit_replacement_cred = cred;
|
|
|
|
audit_replacement_flag = 1;
|
|
|
|
audit_replacement_vp = vp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Wake up the audit worker to perform the exchange once we
|
|
|
|
* release the mutex.
|
|
|
|
*/
|
2006-06-05 13:43:57 +00:00
|
|
|
cv_signal(&audit_worker_cv);
|
Merge Perforce changes 93512, 93514, 93515 from TrustedBSD audit3
branch:
Integrate audit.c to audit_worker.c, so as to migrate the worker
thread implementation to its own .c file.
Populate audit_worker.c using parts now removed from audit.c:
- Move audit rotation global variables.
- Move audit_record_write(), audit_worker_rotate(),
audit_worker_drain(), audit_worker(), audit_rotate_vnode().
- Create audit_worker_init() from relevant parts of audit_init(),
which now calls this routine.
- Recreate audit_free(), which wraps uma_zfree() so that
audit_record_zone can be static to audit.c.
- Unstaticize various types and variables relating to the audit
record queue so that audit_worker can get to them. We may want
to wrap these in accessor methods at some point.
- Move AUDIT_PRINTF() to audit_private.h.
Addition of audit_worker.c to kernel configuration, missed in
earlier submit.
Obtained from: TrustedBSD Project
2006-03-19 16:03:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Wait for the audit_worker to broadcast that a replacement has
|
|
|
|
* taken place; we know that once this has happened, our vnode
|
|
|
|
* has been replaced in, so we can return successfully.
|
|
|
|
*/
|
|
|
|
AUDIT_PRINTF(("audit_rotate_vnode: waiting for news of "
|
|
|
|
"replacement\n"));
|
|
|
|
cv_wait(&audit_replacement_cv, &audit_mtx);
|
|
|
|
AUDIT_PRINTF(("audit_rotate_vnode: change acknowledged by "
|
|
|
|
"audit_worker (flag " "now %d)\n", audit_replacement_flag));
|
|
|
|
mtx_unlock(&audit_mtx);
|
|
|
|
|
|
|
|
audit_file_rotate_wait = 0; /* We can now request another rotation */
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
audit_worker_init(void)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
|
|
|
cv_init(&audit_replacement_cv, "audit_replacement_cv");
|
|
|
|
error = kthread_create(audit_worker, NULL, &audit_thread, RFHIGHPID,
|
|
|
|
0, "audit_worker");
|
|
|
|
if (error)
|
|
|
|
panic("audit_worker_init: kthread_create returned %d", error);
|
|
|
|
}
|