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