PERFORCE change 163188 for review
Ilias Marinos
marinosi at FreeBSD.org
Sun May 31 18:28:51 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163188
Change 163188 by marinosi at marinosi_redrum on 2009/05/31 18:27:53
-Towards a slice based audit system. The standard audit system is the
base slice.
-Slice's device skeleton moved in //sys/security/audit as rwatson
suggested.
NOT tested.
Affected files ...
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/bsm/audit.h#2 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/appaudit/audit_slice_dev.c#2 delete
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/appaudit/audit_slice_private.h#2 delete
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#2 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.h#2 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_arg.c#2 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_private.h#2 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.c#1 add
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#1 add
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_syscalls.c#2 edit
.. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_worker.c#2 edit
Differences ...
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/bsm/audit.h#2 (text) ====
@@ -126,6 +126,9 @@
#define A_SETQCTRL 36
#define A_GETCOND 37
#define A_SETCOND 38
+#define A_CREATESLICE 39
+#define A_UPDATESLICE 40
+#define A_REMOVESLICE 41
/*
* Audit policy controls.
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#2 (text) ====
@@ -70,6 +70,8 @@
#include <security/audit/audit.h>
#include <security/audit/audit_private.h>
+#include <security/audit/audit_slice.h>
+
#include <vm/uma.h>
static uma_zone_t audit_record_zone;
@@ -81,83 +83,10 @@
SYSCTL_NODE(_security, OID_AUTO, audit, CTLFLAG_RW, 0,
"TrustedBSD audit controls");
-/*
- * Audit control settings that are set/read by system calls and are hence
- * non-static.
- *
- * Define the audit control flags.
- */
-int audit_enabled;
-int audit_suspended;
-/*
- * Flags controlling behavior in low storage situations. Should we panic if
- * a write fails? Should we fail stop if we're out of disk space?
- */
-int audit_panic_on_write_fail;
-int audit_fail_stop;
-int audit_argv;
-int audit_arge;
-
-/*
- * Are we currently "failing stop" due to out of disk space?
- */
-int audit_in_failure;
-
-/*
- * Global audit statistics.
- */
-struct audit_fstat audit_fstat;
-
-/*
- * Preselection mask for non-attributable events.
- */
-struct au_mask audit_nae_mask;
-
+struct audit_slice base_slice;
+struct audit_slice *audit_base_slice = &base_slice;
/*
- * Mutex to protect global variables shared between various threads and
- * processes.
- */
-struct mtx audit_mtx;
-
-/*
- * Queue of audit records ready for delivery to disk. We insert new records
- * at the tail, and remove records from the head. Also, a count of the
- * number of records used for checking queue depth. In addition, a counter
- * of records that we have allocated but are not yet in the queue, which is
- * needed to estimate the total size of the combined set of records
- * outstanding in the system.
- */
-struct kaudit_queue audit_q;
-int audit_q_len;
-int audit_pre_q_len;
-
-/*
- * Audit queue control settings (minimum free, low/high water marks, etc.)
- */
-struct au_qctrl audit_qctrl;
-
-/*
- * Condition variable to signal to the worker that it has work to do: either
- * new records are in the queue, or a log replacement is taking place.
- */
-struct cv audit_worker_cv;
-
-/*
- * Condition variable to flag when crossing the low watermark, meaning that
- * threads blocked due to hitting the high watermark can wake up and continue
- * to commit records.
- */
-struct cv audit_watermark_cv;
-
-/*
- * Condition variable for auditing threads wait on when in fail-stop mode.
- * Threads wait on this CV forever (and ever), never seeing the light of day
- * again.
- */
-static struct cv audit_fail_cv;
-
-/*
* Kernel audit information. This will store the current audit address
* or host information that the kernel will use when it's generating
* audit records. This data is modified by the A_GET{SET}KAUDIT auditon(2)
@@ -261,38 +190,42 @@
* call into the BSM assembly code to initialize it.
*/
static void
-audit_init(void)
+audit_init(void *arg)
{
- audit_enabled = 0;
- audit_suspended = 0;
- audit_panic_on_write_fail = 0;
- audit_fail_stop = 0;
- audit_in_failure = 0;
- audit_argv = 0;
- audit_arge = 0;
+ struct audit_slice *as = (struct audit_slice *) arg;
+
+ as->audit_enabled = 0;
+ as->audit_suspended = 0;
+ as->audit_panic_on_write_fail = 0;
+ as->audit_fail_stop = 0;
+ as->audit_in_failure = 0;
+ as->audit_argv = 0;
+ as->audit_arge = 0;
+
+
- audit_fstat.af_filesz = 0; /* '0' means unset, unbounded. */
- audit_fstat.af_currsz = 0;
- audit_nae_mask.am_success = 0;
- audit_nae_mask.am_failure = 0;
+ as->audit_fstat.af_filesz = 0; /* '0' means unset, unbounded. */
+ as->audit_fstat.af_currsz = 0;
+ as->audit_nae_mask.am_success = 0;
+ as->audit_nae_mask.am_failure = 0;
- TAILQ_INIT(&audit_q);
- audit_q_len = 0;
- audit_pre_q_len = 0;
- audit_qctrl.aq_hiwater = AQ_HIWATER;
- audit_qctrl.aq_lowater = AQ_LOWATER;
- audit_qctrl.aq_bufsz = AQ_BUFSZ;
- audit_qctrl.aq_minfree = AU_FS_MINFREE;
+ TAILQ_INIT(&(as->audit_q));
+ as->audit_q_len = 0;
+ as->audit_pre_q_len = 0;
+ as->audit_qctrl.aq_hiwater = AQ_HIWATER;
+ as->audit_qctrl.aq_lowater = AQ_LOWATER;
+ as->audit_qctrl.aq_bufsz = AQ_BUFSZ;
+ as->audit_qctrl.aq_minfree = AU_FS_MINFREE;
audit_kinfo.ai_termid.at_type = AU_IPv4;
audit_kinfo.ai_termid.at_addr[0] = INADDR_ANY;
- mtx_init(&audit_mtx, "audit_mtx", NULL, MTX_DEF);
+ mtx_init(&(as->audit_mtx), "audit_mtx", NULL, MTX_DEF);
KINFO_LOCK_INIT();
- cv_init(&audit_worker_cv, "audit_worker_cv");
- cv_init(&audit_watermark_cv, "audit_watermark_cv");
- cv_init(&audit_fail_cv, "audit_fail_cv");
+ cv_init(&(as->audit_worker_cv), "audit_worker_cv");
+ cv_init(&(as->audit_watermark_cv), "audit_watermark_cv");
+ cv_init(&(as->audit_fail_cv), "audit_fail_cv");
audit_record_zone = uma_zcreate("audit_record",
sizeof(struct kaudit_record), audit_record_ctor,
@@ -308,10 +241,11 @@
SHUTDOWN_PRI_FIRST);
/* Start audit worker thread. */
- audit_worker_init();
+ audit_worker_init(as);
}
-SYSINIT(audit_init, SI_SUB_AUDIT, SI_ORDER_FIRST, audit_init, NULL);
+/* Init the base slice */
+SYSINIT(audit_init, SI_SUB_AUDIT, SI_ORDER_FIRST, audit_init, &audit_base_slice);
/*
* Drain the audit queue and close the log at shutdown. Note that this can
@@ -352,9 +286,10 @@
struct kaudit_record *ar;
int no_record;
- mtx_lock(&audit_mtx);
- no_record = (audit_suspended || !audit_enabled);
- mtx_unlock(&audit_mtx);
+ mtx_lock(&(audit_base_slice->audit_mtx));
+ no_record = (&(audit_base_slice->audit_suspended) ||
+ !(audit_base_slice->audit_enabled));
+ mtx_unlock(&(audit_base_slice->audit_mtx));
if (no_record)
return (NULL);
@@ -366,9 +301,9 @@
ar = uma_zalloc_arg(audit_record_zone, td, M_WAITOK);
ar->k_ar.ar_event = event;
- mtx_lock(&audit_mtx);
- audit_pre_q_len++;
- mtx_unlock(&audit_mtx);
+ mtx_lock(&(audit_base_slice->audit_mtx));
+ audit_base_slice->audit_pre_q_len++;
+ mtx_unlock(&(audit_base_slice->audit_mtx));
return (ar);
}
@@ -397,7 +332,7 @@
* value from the system call and using the appropriate audit mask.
*/
if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID)
- aumask = &audit_nae_mask;
+ aumask = &(audit_base_slice->audit_nae_mask);
else
aumask = &ar->k_ar.ar_subj_amask;
@@ -440,9 +375,9 @@
ar->k_ar_commit |= AR_PRESELECT_PIPE;
if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE |
AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE)) == 0) {
- mtx_lock(&audit_mtx);
- audit_pre_q_len--;
- mtx_unlock(&audit_mtx);
+ mtx_lock(&(audit_base_slice->audit_mtx));
+ audit_base_slice->audit_pre_q_len--;
+ mtx_unlock(&(audit_base_slice->audit_mtx));
audit_free(ar);
return;
}
@@ -455,10 +390,11 @@
* Note: it could be that some records initiated while audit was
* enabled should still be committed?
*/
- mtx_lock(&audit_mtx);
- if (audit_suspended || !audit_enabled) {
- audit_pre_q_len--;
- mtx_unlock(&audit_mtx);
+ mtx_lock(&(audit_base_slice->audit_mtx));
+ if (audit_base_slice->audit_suspended
+ || !audit_base_slice->audit_enabled) {
+ audit_base_slice->audit_pre_q_len--;
+ mtx_unlock(&(audit_base_slice->audit_mtx));
audit_free(ar);
return;
}
@@ -467,14 +403,16 @@
* Constrain the number of committed audit records based on the
* configurable parameter.
*/
- while (audit_q_len >= audit_qctrl.aq_hiwater)
- cv_wait(&audit_watermark_cv, &audit_mtx);
+ while (audit_base_slice->audit_q_len >=
+ audit_base_slice->audit_qctrl.aq_hiwater)
+ cv_wait(&(audit_base_slice->audit_watermark_cv),
+ &(audit_base_slice->audit_mtx));
- TAILQ_INSERT_TAIL(&audit_q, ar, k_q);
- audit_q_len++;
- audit_pre_q_len--;
- cv_signal(&audit_worker_cv);
- mtx_unlock(&audit_mtx);
+ TAILQ_INSERT_TAIL(&(audit_base_slice->audit_q), ar, k_q);
+ audit_base_slice->audit_q_len++;
+ audit_base_slice->audit_pre_q_len--;
+ cv_signal(&(audit_base_slice->audit_worker_cv));
+ mtx_unlock(&(audit_base_slice->audit_mtx));
}
/*
@@ -516,7 +454,7 @@
*/
auid = td->td_ucred->cr_audit.ai_auid;
if (auid == AU_DEFAUDITID)
- aumask = &audit_nae_mask;
+ aumask = &(audit_base_slice->audit_nae_mask);
else
aumask = &td->td_ucred->cr_audit.ai_mask;
@@ -538,9 +476,10 @@
* audit record is still required for this event by
* re-calling au_preselect().
*/
- if (audit_in_failure &&
+ if (audit_base_slice->audit_in_failure &&
priv_check(td, PRIV_AUDIT_FAILSTOP) != 0) {
- cv_wait(&audit_fail_cv, &audit_mtx);
+ cv_wait(&(audit_base_slice->audit_fail_cv),
+ &(audit_base_slice->audit_mtx));
panic("audit_failing_stop: thread continued");
}
td->td_ar = audit_new(event, td);
@@ -656,7 +595,7 @@
cred = td->td_ucred;
auid = cred->cr_audit.ai_auid;
if (auid == AU_DEFAUDITID)
- aumask = &audit_nae_mask;
+ aumask = &(audit_base_slice->audit_nae_mask);
else
aumask = &cred->cr_audit.ai_mask;
/*
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.h#2 (text) ====
@@ -191,7 +191,7 @@
} while (0)
#define AUDIT_SYSCALL_ENTER(code, td) do { \
- if (audit_enabled) { \
+ if (audit_base_slice->audit_enabled) { \
audit_syscall_enter(code, td); \
} \
} while (0)
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_arg.c#2 (text) ====
@@ -50,6 +50,8 @@
#include <security/audit/audit.h>
#include <security/audit/audit_private.h>
+#include <security/audit/audit_slice.h>
+
/*
* Calls to manipulate elements of the audit record structure from system
* call code. Macro wrappers will prevent this functions from being entered
@@ -791,7 +793,7 @@
{
struct kaudit_record *ar;
- if (audit_argv == 0)
+ if (audit_base_slice->audit_argv == 0)
return;
ar = currecord();
@@ -812,7 +814,7 @@
{
struct kaudit_record *ar;
- if (audit_arge == 0)
+ if (audit_base_slice->audit_arge == 0)
return;
ar = currecord();
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_private.h#2 (text) ====
@@ -346,9 +346,6 @@
struct kaudit_record *currecord(void);
void audit_free(struct kaudit_record *ar);
void audit_shutdown(void *arg, int howto);
-void audit_rotate_vnode(struct ucred *cred,
- struct vnode *vp);
-void audit_worker_init(void);
/*
* Audit pipe functions.
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_syscalls.c#2 (text) ====
@@ -49,6 +49,8 @@
#include <security/audit/audit_private.h>
#include <security/mac/mac_framework.h>
+#include <security/audit/audit_slice.h>
+
#ifdef AUDIT
/*
@@ -74,7 +76,8 @@
if (error)
return (error);
- if ((uap->length <= 0) || (uap->length > audit_qctrl.aq_bufsz))
+ if ((uap->length <= 0) || (uap->length >
+ audit_base_slice->audit_qctrl.aq_bufsz))
return (EINVAL);
ar = currecord();
@@ -218,25 +221,25 @@
case A_OLDGETPOLICY:
case A_GETPOLICY:
if (uap->length == sizeof(udata.au_policy64)) {
- if (!audit_fail_stop)
+ if (!audit_base_slice->audit_fail_stop)
udata.au_policy64 |= AUDIT_CNT;
- if (audit_panic_on_write_fail)
+ if (audit_base_slice->audit_panic_on_write_fail)
udata.au_policy64 |= AUDIT_AHLT;
- if (audit_argv)
+ if (audit_base_slice->audit_argv)
udata.au_policy64 |= AUDIT_ARGV;
- if (audit_arge)
+ if (audit_base_slice->audit_arge)
udata.au_policy64 |= AUDIT_ARGE;
break;
}
if (uap->length != sizeof(udata.au_policy))
return (EINVAL);
- if (!audit_fail_stop)
+ if (!audit_base_slice->audit_fail_stop)
udata.au_policy |= AUDIT_CNT;
- if (audit_panic_on_write_fail)
+ if (audit_base_slice->audit_panic_on_write_fail)
udata.au_policy |= AUDIT_AHLT;
- if (audit_argv)
+ if (audit_base_slice->audit_argv)
udata.au_policy |= AUDIT_ARGV;
- if (audit_arge)
+ if (audit_base_slice->audit_arge)
udata.au_policy |= AUDIT_ARGE;
break;
@@ -246,12 +249,14 @@
if (udata.au_policy & (~AUDIT_CNT|AUDIT_AHLT|
AUDIT_ARGV|AUDIT_ARGE))
return (EINVAL);
- audit_fail_stop = ((udata.au_policy64 & AUDIT_CNT) ==
- 0);
- audit_panic_on_write_fail = (udata.au_policy64 &
- AUDIT_AHLT);
- audit_argv = (udata.au_policy64 & AUDIT_ARGV);
- audit_arge = (udata.au_policy64 & AUDIT_ARGE);
+ audit_base_slice->audit_fail_stop = ((udata.au_policy64
+ & AUDIT_CNT) == 0);
+ audit_base_slice->audit_panic_on_write_fail =
+ (udata.au_policy64 & AUDIT_AHLT);
+ audit_base_slice->audit_argv = (udata.au_policy64
+ & AUDIT_ARGV);
+ audit_base_slice->audit_arge = (udata.au_policy64
+ & AUDIT_ARGE);
break;
}
if (uap->length != sizeof(udata.au_policy))
@@ -262,40 +267,44 @@
/*
* XXX - Need to wake up waiters if the policy relaxes?
*/
- audit_fail_stop = ((udata.au_policy & AUDIT_CNT) == 0);
- audit_panic_on_write_fail = (udata.au_policy & AUDIT_AHLT);
- audit_argv = (udata.au_policy & AUDIT_ARGV);
- audit_arge = (udata.au_policy & AUDIT_ARGE);
+ audit_base_slice->audit_fail_stop =
+ ((udata.au_policy & AUDIT_CNT) == 0);
+ audit_base_slice->audit_panic_on_write_fail =
+ (udata.au_policy & AUDIT_AHLT);
+ audit_base_slice->audit_argv =
+ (udata.au_policy & AUDIT_ARGV);
+ audit_base_slice->audit_arge =
+ (udata.au_policy & AUDIT_ARGE);
break;
case A_GETKMASK:
if (uap->length != sizeof(udata.au_mask))
return (EINVAL);
- udata.au_mask = audit_nae_mask;
+ udata.au_mask = audit_base_slice->audit_nae_mask;
break;
case A_SETKMASK:
if (uap->length != sizeof(udata.au_mask))
return (EINVAL);
- audit_nae_mask = udata.au_mask;
+ audit_base_slice->audit_nae_mask = udata.au_mask;
break;
case A_OLDGETQCTRL:
case A_GETQCTRL:
if (uap->length == sizeof(udata.au_qctrl64)) {
udata.au_qctrl64.aq64_hiwater =
- (u_int64_t)audit_qctrl.aq_hiwater;
+ (u_int64_t)audit_base_slice->audit_qctrl.aq_hiwater;
udata.au_qctrl64.aq64_lowater =
- (u_int64_t)audit_qctrl.aq_lowater;
+ (u_int64_t)audit_base_slice->audit_qctrl.aq_lowater;
udata.au_qctrl64.aq64_bufsz =
- (u_int64_t)audit_qctrl.aq_bufsz;
+ (u_int64_t)audit_base_slice->audit_qctrl.aq_bufsz;
udata.au_qctrl64.aq64_minfree =
- (u_int64_t)audit_qctrl.aq_minfree;
+ (u_int64_t)audit_base_slice->audit_qctrl.aq_minfree;
break;
}
if (uap->length != sizeof(udata.au_qctrl))
return (EINVAL);
- udata.au_qctrl = audit_qctrl;
+ udata.au_qctrl = audit_base_slice->audit_qctrl;
break;
case A_OLDSETQCTRL:
@@ -308,15 +317,16 @@
(udata.au_qctrl64.aq64_minfree < 0) ||
(udata.au_qctrl64.aq64_minfree > 100))
return (EINVAL);
- audit_qctrl.aq_hiwater =
+ audit_base_slice->audit_qctrl.aq_hiwater =
(int)udata.au_qctrl64.aq64_hiwater;
- audit_qctrl.aq_lowater =
+ audit_base_slice->audit_qctrl.aq_lowater =
(int)udata.au_qctrl64.aq64_lowater;
- audit_qctrl.aq_bufsz =
+ audit_base_slice->audit_qctrl.aq_bufsz =
(int)udata.au_qctrl64.aq64_bufsz;
- audit_qctrl.aq_minfree =
+ audit_base_slice->audit_qctrl.aq_minfree =
(int)udata.au_qctrl64.aq64_minfree;
- audit_qctrl.aq_delay = -1; /* Not used. */
+ /* Not used. */
+ audit_base_slice->audit_qctrl.aq_delay = -1;
break;
}
if (uap->length != sizeof(udata.au_qctrl))
@@ -328,9 +338,9 @@
(udata.au_qctrl.aq_minfree > 100))
return (EINVAL);
- audit_qctrl = udata.au_qctrl;
+ audit_base_slice->audit_qctrl = udata.au_qctrl;
/* XXX The queue delay value isn't used with the kernel. */
- audit_qctrl.aq_delay = -1;
+ audit_base_slice->audit_qctrl.aq_delay = -1;
break;
case A_GETCWD:
@@ -360,7 +370,8 @@
case A_OLDGETCOND:
case A_GETCOND:
if (uap->length == sizeof(udata.au_cond64)) {
- if (audit_enabled && !audit_suspended)
+ if (audit_base_slice->audit_enabled
+ && !audit_base_slice->audit_suspended)
udata.au_cond64 = AUC_AUDITING;
else
udata.au_cond64 = AUC_NOAUDIT;
@@ -368,7 +379,8 @@
}
if (uap->length != sizeof(udata.au_cond))
return (EINVAL);
- if (audit_enabled && !audit_suspended)
+ if (audit_base_slice->audit_enabled
+ && !audit_base_slice->audit_suspended)
udata.au_cond = AUC_AUDITING;
else
udata.au_cond = AUC_NOAUDIT;
@@ -378,11 +390,11 @@
case A_SETCOND:
if (uap->length == sizeof(udata.au_cond64)) {
if (udata.au_cond64 == AUC_NOAUDIT)
- audit_suspended = 1;
+ audit_base_slice->audit_suspended = 1;
if (udata.au_cond64 == AUC_AUDITING)
- audit_suspended = 0;
+ audit_base_slice->audit_suspended = 0;
if (udata.au_cond64 == AUC_DISABLED) {
- audit_suspended = 1;
+ audit_base_slice->audit_suspended = 1;
audit_shutdown(NULL, 0);
}
break;
@@ -390,11 +402,11 @@
if (uap->length != sizeof(udata.au_cond))
return (EINVAL);
if (udata.au_cond == AUC_NOAUDIT)
- audit_suspended = 1;
+ audit_base_slice->audit_suspended = 1;
if (udata.au_cond == AUC_AUDITING)
- audit_suspended = 0;
+ audit_base_slice->audit_suspended = 0;
if (udata.au_cond == AUC_DISABLED) {
- audit_suspended = 1;
+ audit_base_slice->audit_suspended = 1;
audit_shutdown(NULL, 0);
}
break;
@@ -474,14 +486,17 @@
if ((udata.au_fstat.af_filesz != 0) &&
(udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE))
return (EINVAL);
- audit_fstat.af_filesz = udata.au_fstat.af_filesz;
+ audit_base_slice->audit_fstat.af_filesz
+ = udata.au_fstat.af_filesz;
break;
case A_GETFSIZE:
if (uap->length != sizeof(udata.au_fstat))
return (EINVAL);
- udata.au_fstat.af_filesz = audit_fstat.af_filesz;
- udata.au_fstat.af_currsz = audit_fstat.af_currsz;
+ udata.au_fstat.af_filesz
+ = audit_base_slice->audit_fstat.af_filesz;
+ udata.au_fstat.af_currsz
+ = audit_base_slice->audit_fstat.af_currsz;
break;
case A_GETPINFO_ADDR:
@@ -525,6 +540,21 @@
return (EINVAL);
return (audit_send_trigger(udata.au_trigger));
+ case A_CREATESLICE:
+ //if (uap->length != sizeof(udata.au_slice))
+ // return (EINVAL);
+ return (0);
+
+ case A_UPDATESLICE:
+ //if (uap->length != sizeof(udata.au_slice))
+ // return (EINVAL);
+ return (0);
+
+ case A_REMOVESLICE:
+ //if (uap->length != sizeof(udata.au_slice))
+ // return (EINVAL);
+ return (0);
+
default:
return (EINVAL);
}
@@ -805,7 +835,7 @@
* XXXAUDIT: Should audit_suspended actually be cleared by
* audit_worker?
*/
- audit_suspended = 0;
+ audit_base_slice->audit_suspended = 0;
audit_rotate_vnode(cred, vp);
==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_worker.c#2 (text) ====
@@ -69,33 +69,20 @@
#include <security/audit/audit.h>
#include <security/audit/audit_private.h>
+#include <security/audit/audit_slice.h>
+
#include <vm/uma.h>
-/*
- * Worker thread that will schedule disk I/O, etc.
- */
-static struct proc *audit_thread;
/*
- * audit_cred and audit_vp are the stored credential and vnode to use for
- * active audit trail. They are protected by the audit worker lock, which
- * will be held across all I/O and all rotation to prevent them from being
- * replaced (rotated) while in use. The audit_file_rotate_wait flag is set
- * when the kernel has delivered a trigger to auditd to rotate the trail, and
- * is cleared when the next rotation takes place. It is also protected by
- * the audit worker lock.
+ * Slice-worker private mtx handling macros
*/
-static int audit_file_rotate_wait;
-static struct ucred *audit_cred;
-static struct vnode *audit_vp;
-static struct sx audit_worker_lock;
-
-#define AUDIT_WORKER_LOCK_INIT() sx_init(&audit_worker_lock, \
+#define AUDIT_WORKER_LOCK_INIT() sx_init(&(as->audit_worker_lock), \
"audit_worker_lock");
-#define AUDIT_WORKER_LOCK_ASSERT() sx_assert(&audit_worker_lock, \
+#define AUDIT_WORKER_LOCK_ASSERT() sx_assert(&(as->audit_worker_lock), \
SA_XLOCKED)
-#define AUDIT_WORKER_LOCK() sx_xlock(&audit_worker_lock)
-#define AUDIT_WORKER_UNLOCK() sx_xunlock(&audit_worker_lock)
+#define AUDIT_WORKER_LOCK() sx_xlock(&(as->audit_worker_lock))
+#define AUDIT_WORKER_UNLOCK() sx_xunlock(&(as->audit_worker_lock))
/*
* Write an audit record to a file, performed as the last stage after both
@@ -106,7 +93,7 @@
* the audit daemon, since the message is asynchronous anyway.
*/
static void
-audit_record_write(struct vnode *vp, struct ucred *cred, void *data,
+audit_record_write(struct audit_slice *as, void *data,
size_t len)
{
static struct timeval last_lowspace_trigger;
@@ -120,26 +107,26 @@
AUDIT_WORKER_LOCK_ASSERT();
- if (vp == NULL)
+ if (as->audit_vp == NULL)
return;
- mnt_stat = &vp->v_mount->mnt_stat;
- vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+ mnt_stat = &as->audit_vp->v_mount->mnt_stat;
+ vfslocked = VFS_LOCK_GIANT(as->audit_vp->v_mount);
/*
* First, gather statistics on the audit log file and file system so
* that we know how we're doing on space. Consider failure of these
* operations to indicate a future inability to write to the file.
*/
- error = VFS_STATFS(vp->v_mount, mnt_stat, curthread);
+ error = VFS_STATFS(as->audit_vp->v_mount, mnt_stat, curthread);
if (error)
goto fail;
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp, 0);
+ vn_lock(as->audit_vp, LK_EXCLUSIVE | LK_RETRY);
+ error = VOP_GETATTR(as->audit_vp, &vattr, as->audit_cred);
+ VOP_UNLOCK(as->audit_vp, 0);
if (error)
goto fail;
- audit_fstat.af_currsz = vattr.va_size;
+ as->audit_fstat.af_currsz = vattr.va_size;
/*
* We handle four different space-related limits:
@@ -177,16 +164,16 @@
* the daemon a trigger and continue processing the record. Triggers
* are limited to 1/sec.
*/
- if (audit_qctrl.aq_minfree != 0) {
- temp = mnt_stat->f_blocks / (100 / audit_qctrl.aq_minfree);
+ if (as->audit_qctrl.aq_minfree != 0) {
+ temp = mnt_stat->f_blocks / (100 / as->audit_qctrl.aq_minfree);
if (mnt_stat->f_bfree < temp) {
if (ppsratecheck(&last_lowspace_trigger,
&cur_lowspace_trigger, 1)) {
(void)audit_send_trigger(
AUDIT_TRIGGER_LOW_SPACE);
printf("Warning: disk space low (< %d%% free) "
- "on audit log file-system\n",
- audit_qctrl.aq_minfree);
+ "on audit log file-system for %s slice.\n",
+ as->audit_qctrl.aq_minfree, as->as_name);
}
}
}
@@ -196,11 +183,11 @@
* to the daemon. This is only approximate, which is fine as more
* records may be generated before the daemon rotates the file.
*/
- if ((audit_fstat.af_filesz != 0) && (audit_file_rotate_wait == 0) &&
- (vattr.va_size >= audit_fstat.af_filesz)) {
+ if ((as->audit_fstat.af_filesz != 0) && (as->audit_file_rotate_wait == 0) &&
+ (vattr.va_size >= as->audit_fstat.af_filesz)) {
AUDIT_WORKER_LOCK_ASSERT();
- audit_file_rotate_wait = 1;
+ as->audit_file_rotate_wait = 1;
(void)audit_send_trigger(AUDIT_TRIGGER_ROTATE_KERNEL);
}
@@ -215,16 +202,16 @@
* allow operation to continue, but this behavior is sufficient to
* meet fail stop requirements in CAPP.
*/
- if (audit_fail_stop) {
- if ((unsigned long)((audit_q_len + audit_pre_q_len + 1) *
+ if (as->audit_fail_stop) {
+ if ((unsigned long)((as->audit_q_len + as->audit_pre_q_len + 1) *
MAX_AUDIT_RECORD_SIZE) / mnt_stat->f_bsize >=
(unsigned long)(mnt_stat->f_bfree)) {
if (ppsratecheck(&last_fail, &cur_fail, 1))
printf("audit_record_write: free space "
- "below size of audit queue, failing "
- "stop\n");
- audit_in_failure = 1;
- } else if (audit_in_failure) {
+ "below size of audit queue, %s slice failing "
+ "stop\n", as->as_name);
+ as->audit_in_failure = 1;
+ } else if (as->audit_in_failure) {
/*
* Note: if we want to handle recovery, this is the
* spot to do it: unset audit_in_failure, and issue a
@@ -233,8 +220,8 @@
}
}
- error = vn_rdwr(UIO_WRITE, vp, data, len, (off_t)0, UIO_SYSSPACE,
- IO_APPEND|IO_UNIT, cred, NULL, NULL, curthread);
+ error = vn_rdwr(UIO_WRITE, as->audit_vp, data, len, (off_t)0, UIO_SYSSPACE,
+ IO_APPEND|IO_UNIT, as->audit_cred, NULL, NULL, curthread);
if (error == ENOSPC)
goto fail_enospc;
else if (error)
@@ -249,11 +236,11 @@
* Note: if we handle recovery from audit_in_failure, then we need to
* make panic here conditional.
*/
- if (audit_in_failure) {
- if (audit_q_len == 0 && audit_pre_q_len == 0) {
- VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
- (void)VOP_FSYNC(vp, MNT_WAIT, curthread);
- VOP_UNLOCK(vp, 0);
+ if (as->audit_in_failure) {
+ if (as->audit_q_len == 0 && as->audit_pre_q_len == 0) {
+ VOP_LOCK(as->audit_vp, LK_EXCLUSIVE | LK_RETRY);
+ (void)VOP_FSYNC(as->audit_vp, MNT_WAIT, curthread);
+ VOP_UNLOCK(as->audit_vp, 0);
panic("Audit store overflow; record queue drained.");
}
}
@@ -267,14 +254,14 @@
* this can reflect either our preemptive detection of insufficient
* space, or ENOSPC returned by the vnode write call.
*/
- if (audit_fail_stop) {
- VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
- (void)VOP_FSYNC(vp, MNT_WAIT, curthread);
- VOP_UNLOCK(vp, 0);
+ if (as->audit_fail_stop) {
+ VOP_LOCK(as->audit_vp, LK_EXCLUSIVE | LK_RETRY);
+ (void)VOP_FSYNC(as->audit_vp, MNT_WAIT, curthread);
+ VOP_UNLOCK(as->audit_vp, 0);
panic("Audit log space exhausted and fail-stop set.");
}
(void)audit_send_trigger(AUDIT_TRIGGER_NO_SPACE);
- audit_suspended = 1;
+ as->audit_suspended = 1;
/* FALLTHROUGH */
fail:
@@ -282,10 +269,10 @@
* We have failed to write to the file, so the current record is
* lost, which may require an immediate system halt.
*/
- if (audit_panic_on_write_fail) {
- VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
- (void)VOP_FSYNC(vp, MNT_WAIT, curthread);
- VOP_UNLOCK(vp, 0);
+ if (as->audit_panic_on_write_fail) {
+ VOP_LOCK(as->audit_vp, LK_EXCLUSIVE | LK_RETRY);
+ (void)VOP_FSYNC(as->audit_vp, MNT_WAIT, curthread);
+ VOP_UNLOCK(as->audit_vp, 0);
panic("audit_worker: write error %d\n", error);
} else if (ppsratecheck(&last_fail, &cur_fail, 1))
printf("audit_worker: write error %d\n", error);
@@ -300,7 +287,7 @@
* written to disk, and audit pipes.
*/
static void
-audit_worker_process_record(struct kaudit_record *ar)
+audit_worker_process_record(struct kaudit_record *ar, struct audit_slice *as)
{
struct au_record *bsm;
au_class_t class;
@@ -329,7 +316,7 @@
if ((ar->k_ar_commit & AR_COMMIT_USER) &&
(ar->k_ar_commit & AR_PRESELECT_USER_TRAIL)) {
AUDIT_WORKER_LOCK_ASSERT();
- audit_record_write(audit_vp, audit_cred, ar->k_udata,
+ audit_record_write(as, ar->k_udata,
ar->k_ulen);
}
@@ -368,7 +355,7 @@
if (ar->k_ar_commit & AR_PRESELECT_TRAIL) {
AUDIT_WORKER_LOCK_ASSERT();
- audit_record_write(audit_vp, audit_cred, bsm->data, bsm->len);
+ audit_record_write(as, bsm->data, bsm->len);
}
if (ar->k_ar_commit & AR_PRESELECT_PIPE)
@@ -398,16 +385,18 @@
struct kaudit_record *ar;
int lowater_signal;
+ struct audit_slice *as = (struct audit_slice * ) arg;
+
TAILQ_INIT(&ar_worklist);
- mtx_lock(&audit_mtx);
+ mtx_lock(&(as->audit_mtx));
while (1) {
- mtx_assert(&audit_mtx, MA_OWNED);
+ mtx_assert(&(as->audit_mtx), MA_OWNED);
/*
* Wait for a record.
*/
- while (TAILQ_EMPTY(&audit_q))
- cv_wait(&audit_worker_cv, &audit_mtx);
+ while (TAILQ_EMPTY(&(as->audit_q)))
+ cv_wait(&(as->audit_worker_cv), &(as->audit_mtx));
/*
* If there are records in the global audit record queue,
@@ -417,23 +406,23 @@
* continue generating records.
*/
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)
+ while ((ar = TAILQ_FIRST(&(as->audit_q)))) {
+ TAILQ_REMOVE(&(as->audit_q), ar, k_q);
+ as->audit_q_len--;
+ if (as->audit_q_len == as->audit_qctrl.aq_lowater)
lowater_signal++;
TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q);
}
if (lowater_signal)
- cv_broadcast(&audit_watermark_cv);
+ cv_broadcast(&(as->audit_watermark_cv));
- mtx_unlock(&audit_mtx);
+ mtx_unlock(&(as->audit_mtx));
while ((ar = TAILQ_FIRST(&ar_worklist))) {
TAILQ_REMOVE(&ar_worklist, ar, k_q);
- audit_worker_process_record(ar);
+ audit_worker_process_record(ar, as);
audit_free(ar);
}
- mtx_lock(&audit_mtx);
+ mtx_lock(&(as->audit_mtx));
}
}
@@ -451,8 +440,11 @@
{
struct ucred *old_audit_cred;
struct vnode *old_audit_vp;
+ struct audit_slice *as;
int vfslocked;
+ as = audit_base_slice;
+
KASSERT((cred != NULL && vp != NULL) || (cred == NULL && vp == NULL),
("audit_rotate_vnode: cred %p vp %p", cred, vp));
@@ -461,12 +453,12 @@
* send a rotate trigger if the new file fills.
*/
AUDIT_WORKER_LOCK();
- old_audit_cred = audit_cred;
- old_audit_vp = audit_vp;
- audit_cred = cred;
- audit_vp = vp;
- audit_file_rotate_wait = 0;
- audit_enabled = (audit_vp != NULL);
+ old_audit_cred = as->audit_cred;
+ old_audit_vp = as->audit_vp;
+ as->audit_cred = cred;
+ as->audit_vp = vp;
+ as->audit_file_rotate_wait = 0;
+ as->audit_enabled = (as->audit_vp != NULL);
AUDIT_WORKER_UNLOCK();
/*
@@ -482,13 +474,14 @@
}
void
-audit_worker_init(void)
+audit_worker_init(void *arg)
{
int error;
+ struct audit_slice *as = (struct audit_slice * ) arg;
AUDIT_WORKER_LOCK_INIT();
- error = kproc_create(audit_worker, NULL, &audit_thread, RFHIGHPID,
- 0, "audit");
+ error = kproc_create(audit_worker,(void *) as, &(as->audit_thread), RFHIGHPID,
+ 0, as->as_name);
if (error)
panic("audit_worker_init: kproc_create returned %d", error);
}
More information about the p4-projects
mailing list