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