PERFORCE change 143426 for review

Wayne Salamon wsalamon at FreeBSD.org
Fri Jun 13 20:00:38 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=143426

Change 143426 by wsalamon at vh2 on 2008/06/13 19:59:59

	Implement MAC policy pre/post-selection of audit events. This requires		a change to the parameters to the audit syscall exit handler, passing
	in the syscall code now.
	On the audit side, call the MAC pre/post-select functions and 
	either force the event to be audited, drop the event, or allow the
	normal pre-selection to take place.
	On the MAC side, call each policy's audit pre/post-selection policy
	operation.
	Add the pre/post-select function pointer to the ops structure.
	Modify the syscall handlers in all architectures to add the code
	parameter to the audit macro.

Affected files ...

.. //depot/projects/trustedbsd/audit_mac/src/sys/amd64/amd64/trap.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/amd64/ia32/ia32_syscall.c#2 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/arm/arm/trap.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/i386/i386/trap.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/ia64/ia32/ia32_trap.c#2 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/ia64/ia64/trap.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/kern/kern_exit.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/kern/kern_thread.c#5 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/powerpc/aim/trap.c#4 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/powerpc/booke/trap.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/security/audit/audit.c#7 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/security/audit/audit.h#6 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/security/mac/mac_audit.c#4 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/security/mac/mac_framework.h#4 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/security/mac/mac_policy.h#6 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/sparc64/sparc64/trap.c#3 edit
.. //depot/projects/trustedbsd/audit_mac/src/sys/sun4v/sun4v/trap.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/audit_mac/src/sys/amd64/amd64/trap.c#3 (text+ko) ====

@@ -841,7 +841,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, argp);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 	}
 
 	switch (error) {

==== //depot/projects/trustedbsd/audit_mac/src/sys/amd64/ia32/ia32_syscall.c#2 (text+ko) ====

@@ -180,7 +180,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, args64);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 	}
 
 	switch (error) {

==== //depot/projects/trustedbsd/audit_mac/src/sys/arm/arm/trap.c#3 (text+ko) ====

@@ -927,7 +927,7 @@
 		PTRACESTOP_SC(p, td, S_PT_SCE);
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, args);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 		KASSERT(td->td_ar == NULL, 
 		    ("returning from syscall with td_ar set!"));
 	}

==== //depot/projects/trustedbsd/audit_mac/src/sys/i386/i386/trap.c#3 (text+ko) ====

@@ -1024,7 +1024,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, args);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 	}
 
 	switch (error) {

==== //depot/projects/trustedbsd/audit_mac/src/sys/ia64/ia32/ia32_trap.c#2 (text+ko) ====

@@ -126,7 +126,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, args64);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 	}
 
 	switch (error) {

==== //depot/projects/trustedbsd/audit_mac/src/sys/ia64/ia64/trap.c#3 (text+ko) ====

@@ -1030,7 +1030,7 @@
 
 	AUDIT_SYSCALL_ENTER(code, td);
 	error = (*callp->sy_call)(td, args);
-	AUDIT_SYSCALL_EXIT(error, td);
+	AUDIT_SYSCALL_EXIT(code, error, td);
 
 	if (error != EJUSTRETURN) {
 		/*

==== //depot/projects/trustedbsd/audit_mac/src/sys/kern/kern_exit.c#3 (text+ko) ====

@@ -60,6 +60,7 @@
 #include <sys/signalvar.h>
 #include <sys/sched.h>
 #include <sys/sx.h>
+#include <sys/syscall.h>
 #include <sys/syscallsubr.h>
 #include <sys/syslog.h>
 #include <sys/ptrace.h>
@@ -201,7 +202,7 @@
 	 * what the return value is.
 	 */
 	AUDIT_ARG(exit, WEXITSTATUS(rv), 0);
-	AUDIT_SYSCALL_EXIT(0, td);
+	AUDIT_SYSCALL_EXIT(SYS_exit, 0, td);
 #endif
 
 	/* Are we a task leader? */

==== //depot/projects/trustedbsd/audit_mac/src/sys/kern/kern_thread.c#5 (text+ko) ====

@@ -41,6 +41,7 @@
 #include <sys/sched.h>
 #include <sys/sleepqueue.h>
 #include <sys/selinfo.h>
+#include <sys/syscall.h>
 #include <sys/turnstile.h>
 #include <sys/ktr.h>
 #include <sys/umtx.h>
@@ -342,7 +343,7 @@
 	KASSERT(TAILQ_EMPTY(&td->td_sigqueue.sq_list), ("signal pending"));
 
 #ifdef AUDIT
-	AUDIT_SYSCALL_EXIT(0, td);
+	AUDIT_SYSCALL_EXIT(SYS_thr_exit, 0, td);
 #endif
 	umtx_thread_exit(td);
 	/*

==== //depot/projects/trustedbsd/audit_mac/src/sys/powerpc/aim/trap.c#4 (text+ko) ====

@@ -419,7 +419,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, params);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 
 		CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", td->td_name,
 		     syscallnames[code], td->td_retval[0]);

==== //depot/projects/trustedbsd/audit_mac/src/sys/powerpc/booke/trap.c#3 (text+ko) ====

@@ -413,7 +413,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, params);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 
 		CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", p->p_comm,
 		     syscallnames[code], td->td_retval[0]);

==== //depot/projects/trustedbsd/audit_mac/src/sys/security/audit/audit.c#7 (text) ====

@@ -70,6 +70,11 @@
 #include <security/audit/audit.h>
 #include <security/audit/audit_private.h>
 
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#include <security/mac/mac_policy.h>
+#endif
+
 #include <vm/uma.h>
 
 static uma_zone_t	audit_record_zone;
@@ -499,6 +504,19 @@
 	 * Allocate an audit record, if preselection allows it, and store in
 	 * the thread for later use.
 	 */
+#ifdef MAC
+do {
+	int ret;
+	ret = mac_audit_check_preselect(td->td_ucred, event);
+	if (ret == MAC_AUDIT_YES) {
+		td->td_ar = audit_new(event, td);
+		td->td_ar->k_ar.ar_forced_by_mac = 1;
+	}
+	else if (ret == MAC_AUDIT_NO) {
+		td->td_ar = NULL;
+	}
+	else {	/* MAC_AUDIT_DEFAULT */
+#endif
 	class = au_event_class(event);
 	if (au_preselect(event, class, aumask, AU_PRS_BOTH)) {
 		/*
@@ -523,6 +541,10 @@
 		td->td_ar = audit_new(event, td);
 	else
 		td->td_ar = NULL;
+#ifdef MAC
+	}
+} while (0);
+#endif
 }
 
 /*
@@ -531,7 +553,7 @@
  * for committing the audit record, if any, along with return condition.
  */
 void
-audit_syscall_exit(int error, struct thread *td)
+audit_syscall_exit(unsigned int code, int error, struct thread *td)
 {
 	int retval;
 
@@ -547,6 +569,25 @@
 	else
 		retval = td->td_retval[0];
 
+#ifdef MAC
+do {
+	int ret;
+
+	if (td->td_ar == NULL)	/* syscall wasn't audited due to preselect */
+		return;
+
+	ret = mac_audit_check_postselect(td->td_ucred, 
+	    td->td_proc->p_sysent->sv_table[code].sy_auevent, error, retval,
+	    td->td_ar->k_ar.ar_forced_by_mac);
+	if (ret == MAC_AUDIT_YES)
+		td->td_ar->k_ar_commit |= AR_COMMIT_KERNEL;
+	else if (ret == MAC_AUDIT_NO) {
+		audit_free(td->td_ar);	/* Nobody gets the record, not even
+					   pipes or other listeners */
+		return;
+	}
+} while (0);
+#endif
 	audit_commit(td->td_ar, error, retval);
 	td->td_ar = NULL;
 }

==== //depot/projects/trustedbsd/audit_mac/src/sys/security/audit/audit.h#6 (text) ====

@@ -120,7 +120,7 @@
 #define	ARG_ALL			0xFFFFFFFFFFFFFFFFULL
 
 void	 audit_syscall_enter(unsigned short code, struct thread *td);
-void	 audit_syscall_exit(int error, struct thread *td);
+void	 audit_syscall_exit(unsigned int code, int error, struct thread *td);
 
 /*
  * The remaining kernel functions are conditionally compiled in as they are
@@ -216,9 +216,9 @@
  * auditing is enabled, or we have a audit record on the thread.  It is
  * possible that an audit record was begun before auditing was turned off.
  */
-#define	AUDIT_SYSCALL_EXIT(error, td)	do {				\
+#define	AUDIT_SYSCALL_EXIT(code, error, td)	do {			\
 	if (audit_enabled || (td->td_ar != NULL))			\
-		audit_syscall_exit(error, td);				\
+		audit_syscall_exit(code, error, td);			\
 } while (0)
 
 /*
@@ -237,7 +237,7 @@
 #define	AUDIT_SYSCALL_ENTER(code, td)	do {				\
 } while (0)
 
-#define	AUDIT_SYSCALL_EXIT(error, td)	do {				\
+#define	AUDIT_SYSCALL_EXIT(code, error, td)	do {			\
 } while (0)
 
 #define	AUDIT_SYSCLOSE(p, fd)	do {					\

==== //depot/projects/trustedbsd/audit_mac/src/sys/security/mac/mac_audit.c#4 (text+ko) ====

@@ -150,18 +150,63 @@
 int                     
 mac_audit_check_preselect(struct ucred *cred, au_event_t event)
 {
-	int ret;
+	struct mac_policy_conf *mpc;
+	int ret, sel;
+	int entrycount;
 
 	ret = MAC_AUDIT_DEFAULT;
+	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
+		if (mpc->mpc_ops->mpo_audit_check_preselect != NULL) {
+			sel = mpc->mpc_ops->mpo_audit_check_preselect(
+			    cred, event);
+			ret = (ret > sel ? ret : sel);
+		}
+	}
+	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {
+		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
+			if (mpc->mpc_ops->mpo_audit_check_preselect != NULL) {
+				sel = mpc->mpc_ops->mpo_audit_check_preselect(
+				    cred, event);
+				ret = (ret > sel ? ret : sel);
+			}
+		}
+		mac_policy_list_unbusy();
+	}
 	return (ret);
 }
 
 int
 mac_audit_check_postselect(struct ucred *cred, au_event_t event, int error,
-    int retval)
+    int retval, int mac_forced)
 {
-	int ret;
+	struct mac_policy_conf *mpc;
+	int ret, sel;
+	int entrycount;
+
+	/*
+	 * If the audit event was forced by a MAC policy during preselection,
+	 * then post-selection doesn't matter.
+	 */
+	if (mac_forced)
+		return (MAC_AUDIT_YES);
 
 	ret = MAC_AUDIT_DEFAULT;
+	LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
+		if (mpc->mpc_ops->mpo_audit_check_postselect != NULL) {
+			sel = mpc->mpc_ops->mpo_audit_check_postselect(
+			    cred, event, error, retval);
+			ret = (ret > sel ? ret : sel);
+		}
+	}
+	if ((entrycount = mac_policy_list_conditional_busy()) != 0) {
+		LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
+			if (mpc->mpc_ops->mpo_audit_check_postselect != NULL) {
+				sel = mpc->mpc_ops->mpo_audit_check_postselect(
+				    cred, event, error, retval);
+				ret = (ret > sel ? ret : sel);
+			}
+		}
+		mac_policy_list_unbusy();
+	}
 	return (ret);
 }

==== //depot/projects/trustedbsd/audit_mac/src/sys/security/mac/mac_framework.h#4 (text+ko) ====

@@ -92,7 +92,7 @@
 
 int	mac_audit_check_preselect(struct ucred *cred, au_event_t event);
 int	mac_audit_check_postselect(struct ucred *cred, au_event_t event,
-    int error, int retval);
+    int error, int retval, int mac_forced);
 
 /*
  * Entry points to the TrustedBSD MAC Framework from the remainder of the

==== //depot/projects/trustedbsd/audit_mac/src/sys/security/mac/mac_policy.h#6 (text+ko) ====

@@ -664,6 +664,13 @@
 	mpo_syscall_t				mpo_syscall;
 
 	/*
+	 * Audit operations. Allow the policy to override pre- and post-
+	 * selection of audit events.
+	 */
+	mpo_audit_check_postselect_t		mpo_audit_check_postselect;
+	mpo_audit_check_preselect_t		mpo_audit_check_preselect;
+
+	/*
 	 * Label operations.  Initialize label storage, destroy label
 	 * storage, recycle for re-use without init/destroy, copy a label to
 	 * initialized storage, and externalize/internalize from/to

==== //depot/projects/trustedbsd/audit_mac/src/sys/sparc64/sparc64/trap.c#3 (text+ko) ====


==== //depot/projects/trustedbsd/audit_mac/src/sys/sun4v/sun4v/trap.c#2 (text+ko) ====

@@ -677,7 +677,7 @@
 
 		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, argp);
-		AUDIT_SYSCALL_EXIT(error, td);
+		AUDIT_SYSCALL_EXIT(code, error, td);
 
 		CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p,
 		    error, syscallnames[code], td->td_retval[0],


More information about the p4-projects mailing list