summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2007-06-07 22:27:15 +0000
committerrwatson <rwatson@FreeBSD.org>2007-06-07 22:27:15 +0000
commit9f332c91ef20b2392e96c3aed469ba04aeb7b13f (patch)
tree23e84b7f5fd5465f12ed2c509373ee128d73a43a /sys
parent1f72bba08402b15a14e6c65f84d0d252f2d2bc1c (diff)
downloadFreeBSD-src-9f332c91ef20b2392e96c3aed469ba04aeb7b13f.zip
FreeBSD-src-9f332c91ef20b2392e96c3aed469ba04aeb7b13f.tar.gz
Move per-process audit state from a pointer in the proc structure to
embedded storage in struct ucred. This allows audit state to be cached with the thread, avoiding locking operations with each system call, and makes it available in asynchronous execution contexts, such as deep in the network stack or VFS. Reviewed by: csjp Approved by: re (kensmith) Obtained from: TrustedBSD Project
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/kern_exit.c3
-rw-r--r--sys/kern/kern_fork.c9
-rw-r--r--sys/kern/kern_prot.c9
-rw-r--r--sys/security/audit/audit.c78
-rw-r--r--sys/security/audit/audit.h10
-rw-r--r--sys/security/audit/audit_arg.c6
-rw-r--r--sys/security/audit/audit_syscalls.c201
-rw-r--r--sys/sys/proc.h2
-rw-r--r--sys/sys/ucred.h3
10 files changed, 147 insertions, 179 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 0be3af3..10996e7 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -441,8 +441,7 @@ proc0_init(void *dummy __unused)
p->p_ucred->cr_ruidinfo = uifind(0);
p->p_ucred->cr_prison = NULL; /* Don't jail it. */
#ifdef AUDIT
- audit_proc_alloc(p);
- audit_proc_kproc0(p);
+ audit_cred_kproc0(p->p_ucred);
#endif
#ifdef MAC
mac_create_proc0(p->p_ucred);
@@ -707,7 +706,7 @@ create_init(const void *udata __unused)
mac_create_proc1(newcred);
#endif
#ifdef AUDIT
- audit_proc_init(initproc);
+ audit_cred_proc1(newcred);
#endif
initproc->p_ucred = newcred;
PROC_UNLOCK(initproc);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 9cab321..eefe6b0 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -811,9 +811,6 @@ loop:
#ifdef MAC
mac_destroy_proc(p);
#endif
-#ifdef AUDIT
- audit_proc_free(p);
-#endif
KASSERT(FIRST_THREAD_IN_PROC(p),
("kern_wait: no residual thread!"));
uma_zfree(proc_zone, p);
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index ae3531c..04b31d4 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -279,9 +279,6 @@ fork1(td, flags, pages, procp)
#ifdef MAC
mac_init_proc(newproc);
#endif
-#ifdef AUDIT
- audit_proc_alloc(newproc);
-#endif
knlist_init(&newproc->p_klist, &newproc->p_mtx, NULL, NULL, NULL);
STAILQ_INIT(&newproc->p_ktr);
@@ -510,9 +507,6 @@ again:
p2->p_sflag = PS_INMEM;
PROC_SUNLOCK(p2);
td2->td_ucred = crhold(p2->p_ucred);
-#ifdef AUDIT
- audit_proc_fork(p1, p2);
-#endif
pargs_hold(p2->p_args);
if (flags & RFSIGSHARE) {
@@ -753,9 +747,6 @@ fail:
#ifdef MAC
mac_destroy_proc(newproc);
#endif
-#ifdef AUDIT
- audit_proc_free(newproc);
-#endif
uma_zfree(proc_zone, newproc);
if (p1->p_flag & P_HADTHREADS) {
PROC_LOCK(p1);
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index a11825a..36a5dc4 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1763,6 +1763,9 @@ crget(void)
MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
refcount_init(&cr->cr_ref, 1);
+#ifdef AUDIT
+ audit_cred_init(cr);
+#endif
#ifdef MAC
mac_init_cred(cr);
#endif
@@ -1804,6 +1807,9 @@ crfree(struct ucred *cr)
*/
if (jailed(cr))
prison_free(cr->cr_prison);
+#ifdef AUDIT
+ audit_cred_destroy(cr);
+#endif
#ifdef MAC
mac_destroy_cred(cr);
#endif
@@ -1836,6 +1842,9 @@ crcopy(struct ucred *dest, struct ucred *src)
uihold(dest->cr_ruidinfo);
if (jailed(dest))
prison_hold(dest->cr_prison);
+#ifdef AUDIT
+ audit_cred_copy(src, dest);
+#endif
#ifdef MAC
mac_copy_cred(src, dest);
#endif
diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c
index 6f1fef6..96ea78b 100644
--- a/sys/security/audit/audit.c
+++ b/sys/security/audit/audit.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1999-2005 Apple Computer, Inc.
- * Copyright (c) 2006 Robert N. M. Watson
+ * Copyright (c) 2006-2007 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@
#include <vm/uma.h>
static uma_zone_t audit_record_zone;
-static MALLOC_DEFINE(M_AUDITPROC, "audit_proc", "Audit process storage");
+static MALLOC_DEFINE(M_AUDITCRED, "audit_cred", "Audit cred storage");
MALLOC_DEFINE(M_AUDITDATA, "audit_data", "Audit data storage");
MALLOC_DEFINE(M_AUDITPATH, "audit_path", "Audit path storage");
MALLOC_DEFINE(M_AUDITTEXT, "audit_text", "Audit text storage");
@@ -176,13 +176,11 @@ audit_record_ctor(void *mem, int size, void *arg, int flags)
ar->k_ar.ar_subj_ruid = td->td_ucred->cr_ruid;
ar->k_ar.ar_subj_rgid = td->td_ucred->cr_rgid;
ar->k_ar.ar_subj_egid = td->td_ucred->cr_groups[0];
- PROC_LOCK(td->td_proc);
- ar->k_ar.ar_subj_auid = td->td_proc->p_au->ai_auid;
- ar->k_ar.ar_subj_asid = td->td_proc->p_au->ai_asid;
+ ar->k_ar.ar_subj_auid = td->td_ucred->cr_audit.ai_auid;
+ ar->k_ar.ar_subj_asid = td->td_ucred->cr_audit.ai_asid;
ar->k_ar.ar_subj_pid = td->td_proc->p_pid;
- ar->k_ar.ar_subj_amask = td->td_proc->p_au->ai_mask;
- ar->k_ar.ar_subj_term_addr = td->td_proc->p_au->ai_termid;
- PROC_UNLOCK(td->td_proc);
+ ar->k_ar.ar_subj_amask = td->td_ucred->cr_audit.ai_mask;
+ ar->k_ar.ar_subj_term_addr = td->td_ucred->cr_audit.ai_termid;
return (0);
}
@@ -470,11 +468,11 @@ audit_syscall_enter(unsigned short code, struct thread *td)
* Check which audit mask to use; either the kernel non-attributable
* event mask or the process audit mask.
*/
- auid = td->td_proc->p_au->ai_auid;
+ auid = td->td_ucred->cr_audit.ai_auid;
if (auid == AU_DEFAUDITID)
aumask = &audit_nae_mask;
else
- aumask = &td->td_proc->p_au->ai_mask;
+ aumask = &td->td_ucred->cr_audit.ai_mask;
/*
* Allocate an audit record, if preselection allows it, and store in
@@ -533,92 +531,68 @@ audit_syscall_exit(int error, struct thread *td)
}
/*
- * Allocate storage for a new process (init, or otherwise).
+ * Copy audit state from an existing credential to a new credential.
*/
void
-audit_proc_alloc(struct proc *p)
+audit_cred_copy(struct ucred *src, struct ucred *dest)
{
- KASSERT(p->p_au == NULL, ("audit_proc_alloc: p->p_au != NULL (%d)",
- p->p_pid));
- p->p_au = malloc(sizeof(*(p->p_au)), M_AUDITPROC, M_WAITOK);
+ bcopy(&src->cr_audit, &dest->cr_audit, sizeof(dest->cr_audit));
}
/*
- * Allocate storage for a new thread.
+ * Free audit state from a credential when the credential is freed.
*/
void
-audit_thread_alloc(struct thread *td)
+audit_cred_destroy(struct ucred *cred)
{
- td->td_ar = NULL;
+ bzero(&cred->cr_audit, sizeof(cred->cr_audit));
}
/*
- * Thread destruction.
+ * Allocate audit state for a new credential.
*/
void
-audit_thread_free(struct thread *td)
+audit_cred_init(struct ucred *cred)
{
- KASSERT(td->td_ar == NULL, ("audit_thread_free: td_ar != NULL"));
+ bzero(&cred->cr_audit, sizeof(cred->cr_audit));
}
/*
* Initialize audit information for the first kernel process (proc 0) and for
* the first user process (init).
- *
- * XXX It is not clear what the initial values should be for audit ID,
- * session ID, etc.
*/
void
-audit_proc_kproc0(struct proc *p)
+audit_cred_kproc0(struct ucred *cred)
{
- KASSERT(p->p_au != NULL, ("audit_proc_kproc0: p->p_au == NULL (%d)",
- p->p_pid));
-
- bzero(p->p_au, sizeof(*(p)->p_au));
}
void
-audit_proc_init(struct proc *p)
+audit_cred_proc1(struct ucred *cred)
{
- KASSERT(p->p_au != NULL, ("audit_proc_init: p->p_au == NULL (%d)",
- p->p_pid));
-
- bzero(p->p_au, sizeof(*(p)->p_au));
- p->p_au->ai_auid = AU_DEFAUDITID;
+ cred->cr_audit.ai_auid = AU_DEFAUDITID;
}
/*
- * Copy the audit info from the parent process to the child process when a
- * fork takes place.
+ * Allocate storage for a new thread.
*/
void
-audit_proc_fork(struct proc *parent, struct proc *child)
+audit_thread_alloc(struct thread *td)
{
- PROC_LOCK_ASSERT(parent, MA_OWNED);
- PROC_LOCK_ASSERT(child, MA_OWNED);
- KASSERT(parent->p_au != NULL,
- ("audit_proc_fork: parent->p_au == NULL (%d)", parent->p_pid));
- KASSERT(child->p_au != NULL,
- ("audit_proc_fork: child->p_au == NULL (%d)", child->p_pid));
-
- bcopy(parent->p_au, child->p_au, sizeof(*child->p_au));
+ td->td_ar = NULL;
}
/*
- * Free the auditing structure for the process.
+ * Thread destruction.
*/
void
-audit_proc_free(struct proc *p)
+audit_thread_free(struct thread *td)
{
- KASSERT(p->p_au != NULL, ("p->p_au == NULL (%d)", p->p_pid));
-
- free(p->p_au, M_AUDITPROC);
- p->p_au = NULL;
+ KASSERT(td->td_ar == NULL, ("audit_thread_free: td_ar != NULL"));
}
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index bfb3b58..6550b09 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -171,11 +171,11 @@ void audit_arg_file(struct proc *p, struct file *fp);
void audit_arg_argv(char *argv, int argc, int length);
void audit_arg_envv(char *envv, int envc, int length);
void audit_sysclose(struct thread *td, int fd);
-void audit_proc_alloc(struct proc *p);
-void audit_proc_kproc0(struct proc *p);
-void audit_proc_init(struct proc *p);
-void audit_proc_fork(struct proc *parent, struct proc *child);
-void audit_proc_free(struct proc *p);
+void audit_cred_copy(struct ucred *src, struct ucred *dest);
+void audit_cred_destroy(struct ucred *cred);
+void audit_cred_init(struct ucred *cred);
+void audit_cred_kproc0(struct ucred *cred);
+void audit_cred_proc1(struct ucred *cred);
void audit_thread_alloc(struct thread *td);
void audit_thread_free(struct thread *td);
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index b5e565a..914f918 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -364,13 +364,13 @@ audit_arg_process(struct proc *p)
if (ar == NULL)
return;
- ar->k_ar.ar_arg_auid = p->p_au->ai_auid;
+ ar->k_ar.ar_arg_auid = p->p_ucred->cr_audit.ai_auid;
ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid;
ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0];
ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid;
ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid;
- ar->k_ar.ar_arg_asid = p->p_au->ai_asid;
- ar->k_ar.ar_arg_termid_addr = p->p_au->ai_termid;
+ ar->k_ar.ar_arg_asid = p->p_ucred->cr_audit.ai_asid;
+ ar->k_ar.ar_arg_termid_addr = p->p_ucred->cr_audit.ai_termid;
ar->k_ar.ar_arg_pid = p->p_pid;
ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
diff --git a/sys/security/audit/audit_syscalls.c b/sys/security/audit/audit_syscalls.c
index cba0aa7..81200ab 100644
--- a/sys/security/audit/audit_syscalls.c
+++ b/sys/security/audit/audit_syscalls.c
@@ -156,6 +156,7 @@ free_out:
int
auditon(struct thread *td, struct auditon_args *uap)
{
+ struct ucred *newcred, *oldcred;
int error;
union auditon_udata udata;
struct proc *tp;
@@ -313,47 +314,53 @@ auditon(struct thread *td, struct auditon_args *uap)
case A_GETPINFO:
if (udata.au_aupinfo.ap_pid < 1)
return (EINVAL);
-
if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
return (EINVAL);
if (p_cansee(td, tp) != 0) {
PROC_UNLOCK(tp);
return (EINVAL);
}
-
- if (tp->p_au->ai_termid.at_type == AU_IPv6) {
+ if (tp->p_ucred->cr_audit.ai_termid.at_type == AU_IPv6) {
PROC_UNLOCK(tp);
return (EINVAL);
}
- udata.au_aupinfo.ap_auid = tp->p_au->ai_auid;
+ udata.au_aupinfo.ap_auid =
+ tp->p_ucred->cr_audit.ai_auid;
udata.au_aupinfo.ap_mask.am_success =
- tp->p_au->ai_mask.am_success;
+ tp->p_ucred->cr_audit.ai_mask.am_success;
udata.au_aupinfo.ap_mask.am_failure =
- tp->p_au->ai_mask.am_failure;
+ tp->p_ucred->cr_audit.ai_mask.am_failure;
udata.au_aupinfo.ap_termid.machine =
- tp->p_au->ai_termid.at_addr[0];
+ tp->p_ucred->cr_audit.ai_termid.at_addr[0];
udata.au_aupinfo.ap_termid.port =
- (dev_t)tp->p_au->ai_termid.at_port;
- udata.au_aupinfo.ap_asid = tp->p_au->ai_asid;
+ (dev_t)tp->p_ucred->cr_audit.ai_termid.at_port;
+ udata.au_aupinfo.ap_asid =
+ tp->p_ucred->cr_audit.ai_asid;
PROC_UNLOCK(tp);
break;
case A_SETPMASK:
if (udata.au_aupinfo.ap_pid < 1)
return (EINVAL);
-
- if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
+ newcred = crget();
+ if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) {
+ crfree(newcred);
return (EINVAL);
+ }
if (p_cansee(td, tp) != 0) {
PROC_UNLOCK(tp);
+ crfree(newcred);
return (EINVAL);
}
-
- tp->p_au->ai_mask.am_success =
+ oldcred = tp->p_ucred;
+ crcopy(newcred, oldcred);
+ newcred->cr_audit.ai_mask.am_success =
udata.au_aupinfo.ap_mask.am_success;
- tp->p_au->ai_mask.am_failure =
+ newcred->cr_audit.ai_mask.am_failure =
udata.au_aupinfo.ap_mask.am_failure;
+ td->td_proc->p_ucred = newcred;
PROC_UNLOCK(tp);
+ crfree(oldcred);
break;
case A_SETFSIZE:
@@ -373,13 +380,16 @@ auditon(struct thread *td, struct auditon_args *uap)
return (EINVAL);
if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL)
return (EINVAL);
- udata.au_aupinfo_addr.ap_auid = tp->p_au->ai_auid;
+ udata.au_aupinfo_addr.ap_auid =
+ tp->p_ucred->cr_audit.ai_auid;
udata.au_aupinfo_addr.ap_mask.am_success =
- tp->p_au->ai_mask.am_success;
+ tp->p_ucred->cr_audit.ai_mask.am_success;
udata.au_aupinfo_addr.ap_mask.am_failure =
- tp->p_au->ai_mask.am_failure;
- udata.au_aupinfo_addr.ap_termid = tp->p_au->ai_termid;
- udata.au_aupinfo_addr.ap_asid = tp->p_au->ai_asid;
+ tp->p_ucred->cr_audit.ai_mask.am_failure;
+ udata.au_aupinfo_addr.ap_termid =
+ tp->p_ucred->cr_audit.ai_termid;
+ udata.au_aupinfo_addr.ap_asid =
+ tp->p_ucred->cr_audit.ai_asid;
PROC_UNLOCK(tp);
break;
@@ -431,64 +441,51 @@ int
getauid(struct thread *td, struct getauid_args *uap)
{
int error;
- au_id_t id;
if (jailed(td->td_ucred))
return (ENOSYS);
error = priv_check(td, PRIV_AUDIT_GETAUDIT);
if (error)
return (error);
-
- /*
- * XXX: Integer read on static pointer dereference: doesn't need
- * locking?
- */
- PROC_LOCK(td->td_proc);
- id = td->td_proc->p_au->ai_auid;
- PROC_UNLOCK(td->td_proc);
- return copyout(&id, uap->auid, sizeof(id));
+ return (copyout(&td->td_ucred->cr_audit.ai_auid, uap->auid,
+ sizeof(td->td_ucred->cr_audit.ai_auid)));
}
/* ARGSUSED */
int
setauid(struct thread *td, struct setauid_args *uap)
{
- int error;
+ struct ucred *newcred, *oldcred;
au_id_t id;
+ int error;
if (jailed(td->td_ucred))
return (ENOSYS);
- error = priv_check(td, PRIV_AUDIT_SETAUDIT);
- if (error)
- return (error);
-
error = copyin(uap->auid, &id, sizeof(id));
if (error)
return (error);
-
audit_arg_auid(id);
-
+ newcred = crget();
+ PROC_LOCK(td->td_proc);
+ oldcred = td->td_proc->p_ucred;
+ crcopy(newcred, oldcred);
#ifdef MAC
- error = mac_check_proc_setauid(td->td_ucred, id);
+ error = mac_check_proc_setauid(oldcred, id);
if (error)
- return (error);
+ goto fail;
#endif
-
- /*
- * XXX: Integer write on static pointer dereference: doesn't need
- * locking?
- *
- * XXXAUDIT: Might need locking to serialize audit events in the same
- * order as change events? Or maybe that's an under-solveable
- * problem.
- *
- * XXXRW: Test privilege while holding the proc lock?
- */
- PROC_LOCK(td->td_proc);
- td->td_proc->p_au->ai_auid = id;
+ error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
+ if (error)
+ goto fail;
+ newcred->cr_audit.ai_auid = id;
+ td->td_proc->p_ucred = newcred;
PROC_UNLOCK(td->td_proc);
-
+ crfree(oldcred);
return (0);
+fail:
+ PROC_UNLOCK(td->td_proc);
+ crfree(newcred);
+ return (error);
}
/*
@@ -506,108 +503,108 @@ getaudit(struct thread *td, struct getaudit_args *uap)
error = priv_check(td, PRIV_AUDIT_GETAUDIT);
if (error)
return (error);
-
- PROC_LOCK(td->td_proc);
- if (td->td_proc->p_au->ai_termid.at_type == AU_IPv6) {
- PROC_UNLOCK(td->td_proc);
- return (E2BIG);
- }
bzero(&ai, sizeof(ai));
- ai.ai_auid = td->td_proc->p_au->ai_auid;
- ai.ai_mask = td->td_proc->p_au->ai_mask;
- ai.ai_asid = td->td_proc->p_au->ai_asid;
- ai.ai_termid.machine = td->td_proc->p_au->ai_termid.at_addr[0];
- ai.ai_termid.port = td->td_proc->p_au->ai_termid.at_port;
- PROC_UNLOCK(td->td_proc);
-
- return (copyout(&ai, uap->auditinfo, sizeof(ai)));
+ ai.ai_auid = td->td_ucred->cr_audit.ai_auid;
+ ai.ai_mask = td->td_ucred->cr_audit.ai_mask;
+ ai.ai_asid = td->td_ucred->cr_audit.ai_asid;
+ ai.ai_termid.machine = td->td_ucred->cr_audit.ai_termid.at_addr[0];
+ ai.ai_termid.port = td->td_ucred->cr_audit.ai_termid.at_port;
+ return (copyout(&ai, uap->auditinfo, sizeof(&ai)));
}
/* ARGSUSED */
int
setaudit(struct thread *td, struct setaudit_args *uap)
{
+ struct ucred *newcred, *oldcred;
struct auditinfo ai;
int error;
if (jailed(td->td_ucred))
return (ENOSYS);
- error = priv_check(td, PRIV_AUDIT_SETAUDIT);
- if (error)
- return (error);
-
error = copyin(uap->auditinfo, &ai, sizeof(ai));
if (error)
return (error);
-
audit_arg_auditinfo(&ai);
-
+ newcred = crget();
+ PROC_LOCK(td->td_proc);
+ oldcred = td->td_proc->p_ucred;
+ crcopy(newcred, oldcred);
#ifdef MAC
- error = mac_check_proc_setaudit(td->td_ucred, &ai);
+ error = mac_check_proc_setaudit(oldcred, &ai);
if (error)
- return (error);
+ goto fail;
#endif
-
- /*
- * XXXRW: Test privilege while holding the proc lock?
- */
- PROC_LOCK(td->td_proc);
- bzero(td->td_proc->p_au, sizeof(struct auditinfo_addr));
- td->td_proc->p_au->ai_auid = ai.ai_auid;
- td->td_proc->p_au->ai_mask = ai.ai_mask;
- td->td_proc->p_au->ai_asid = ai.ai_asid;
- td->td_proc->p_au->ai_termid.at_addr[0] = ai.ai_termid.machine;
- td->td_proc->p_au->ai_termid.at_port = ai.ai_termid.port;
- td->td_proc->p_au->ai_termid.at_type = AU_IPv4;
+ error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
+ if (error)
+ goto fail;
+ bzero(&newcred->cr_audit, sizeof(newcred->cr_audit));
+ newcred->cr_audit.ai_auid = ai.ai_auid;
+ newcred->cr_audit.ai_mask = ai.ai_mask;
+ newcred->cr_audit.ai_asid = ai.ai_asid;
+ newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine;
+ newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port;
+ newcred->cr_audit.ai_termid.at_type = AU_IPv4;
+ td->td_proc->p_ucred = newcred;
PROC_UNLOCK(td->td_proc);
-
+ crfree(oldcred);
return (0);
+fail:
+ PROC_UNLOCK(td->td_proc);
+ crfree(newcred);
+ return (error);
}
/* ARGSUSED */
int
getaudit_addr(struct thread *td, struct getaudit_addr_args *uap)
{
- struct auditinfo_addr aia;
int error;
if (jailed(td->td_ucred))
return (ENOSYS);
+ if (uap->length < sizeof(*uap->auditinfo_addr))
+ return (EOVERFLOW);
error = priv_check(td, PRIV_AUDIT_GETAUDIT);
if (error)
return (error);
- if (uap->length < sizeof(aia))
- return (EOVERFLOW);
- PROC_LOCK(td->td_proc);
- aia = *td->td_proc->p_au;
- PROC_UNLOCK(td->td_proc);
- return (copyout(&aia, uap->auditinfo_addr, sizeof(aia)));
+ return (copyout(&td->td_ucred->cr_audit, uap->auditinfo_addr,
+ sizeof(*uap->auditinfo_addr)));
}
/* ARGSUSED */
int
setaudit_addr(struct thread *td, struct setaudit_addr_args *uap)
{
+ struct ucred *newcred, *oldcred;
struct auditinfo_addr aia;
int error;
if (jailed(td->td_ucred))
return (ENOSYS);
- error = priv_check(td, PRIV_AUDIT_SETAUDIT);
+ error = copyin(uap->auditinfo_addr, &aia, sizeof(aia));
if (error)
return (error);
-
+ /* XXXRW: Audit argument. */
+ newcred = crget();
+ PROC_LOCK(td->td_proc);
+ oldcred = td->td_proc->p_ucred;
+ crcopy(newcred, oldcred);
#ifdef MAC
- error = mac_check_proc_setaudit(td->td_ucred, NULL);
+ error = mac_check_proc_setaudit(oldcred, NULL);
if (error)
- return (error);
+ goto fail;
#endif
- error = copyin(uap->auditinfo_addr, &aia, sizeof(aia));
+ error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
if (error)
- return (error);
- PROC_LOCK(td->td_proc);
- *td->td_proc->p_au = aia;
+ goto fail;
+ newcred->cr_audit = aia;
+ td->td_proc->p_ucred = newcred;
PROC_UNLOCK(td->td_proc);
+ crfree(oldcred);
+ return (0);
+fail:
+ crfree(newcred);
return (error);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index dc8ab6b..4f12015 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -152,7 +152,6 @@ struct pargs {
* either lock is sufficient for read access, but both locks must be held
* for write access.
*/
-struct auditinfo;
struct kaudit_record;
struct td_sched;
struct nlminfo;
@@ -580,7 +579,6 @@ struct proc {
struct p_sched *p_sched; /* (*) Scheduler-specific data. */
STAILQ_HEAD(, ktr_request) p_ktr; /* (o) KTR event queue. */
LIST_HEAD(, mqueue_notifier) p_mqnotifier; /* (c) mqueue notifiers.*/
- struct auditinfo_addr *p_au; /* (c) Process audit properties. */
};
#define p_session p_pgrp->pg_session
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index 03cf5f9..1c8e7c8 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -33,6 +33,8 @@
#ifndef _SYS_UCRED_H_
#define _SYS_UCRED_H_
+#include <bsm/audit.h>
+
/*
* Credentials.
*
@@ -55,6 +57,7 @@ struct ucred {
struct prison *cr_prison; /* jail(2) */
#define cr_endcopy cr_label
struct label *cr_label; /* MAC label */
+ struct auditinfo_addr cr_audit; /* Audit properties. */
};
#define NOCRED ((struct ucred *)0) /* no credential available */
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
OpenPOWER on IntegriCloud