summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
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