From owner-p4-projects@FreeBSD.ORG Sun Jan 11 11:14:03 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 56F2016A4D1; Sun, 11 Jan 2004 11:14:03 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2C4C916A4CE for ; Sun, 11 Jan 2004 11:14:03 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E79BB43D2D for ; Sun, 11 Jan 2004 11:13:54 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i0BJDs0B066966 for ; Sun, 11 Jan 2004 11:13:54 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i0BJDsI6066960 for perforce@freebsd.org; Sun, 11 Jan 2004 11:13:54 -0800 (PST) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sun, 11 Jan 2004 11:13:54 -0800 (PST) Message-Id: <200401111913.i0BJDsI6066960@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Subject: PERFORCE change 45154 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Jan 2004 19:14:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=45154 Change 45154 by rwatson@rwatson_paprika on 2004/01/11 11:12:56 More of the way to audit.c compiling: - Use FreeBSD kthreads, not Mach kthreads. - Namei include required. - UNIX domain socket include required. - Get rid of temporary typedefing and just use FreeBSD mutexes and cv's rather than the Mach mutex and waitqueue APIs, don't even pretend about the funnels. Amazing how much more simple the CV API is. - Remove some undefined variables picked up by FreeBSD use of -Wall. - Comment out the system call table bits -- we'll want to add audit record types to syscalls.master, probably. - Use td->td_ucred rather than p->p_cred->pc_ucred. - Use FreeBSD suser() API. - Don't declare system call argument structures here, that's done for us by virtue of syscalls.master magic. - Use threads instead of processes in VFS situations. - Use struct thread instead of struct uthread; td instead of uu. Affected files ... .. //depot/projects/trustedbsd/audit2/sys/security/audit/audit.c#6 edit .. //depot/projects/trustedbsd/audit2/sys/security/audit/kern_audit.h#4 edit Differences ... ==== //depot/projects/trustedbsd/audit2/sys/security/audit/audit.c#6 (text+ko) ==== @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,14 +38,12 @@ #include #include #include +#include #include #include #include -typedef struct mutex mutex_t; -typedef struct cv wait_queue_t; - #define kmem_alloc(map, ptrref, size) #define kmem_free(map, ptr, size) @@ -51,9 +51,6 @@ vn_rdwr((rw), (vp), (base), (len), (offset), (segflg), (ioflg), \ (cred), NULL, (resid), (td)) -#define mutex_lock(x) mtx_lock(x) -#define mutex_unlock(x) mtx_unlock(x) - #ifdef AUDIT /* @@ -92,7 +89,7 @@ * Mutex to protect global variables shared between various threads and * processes. */ -static mutex_t *audit_mtx; +static struct mtx audit_mtx; /* * Queue of audit records ready for delivery to disk. We insert new @@ -105,7 +102,12 @@ * either new records are in the queue, or a log replacement is taking * place. */ -static wait_queue_t audit_wait_queue; +static struct cv audit_cv; + +/* + * Worker thread that will schedule disk I/O, etc. + */ +static struct proc *audit_thread; /* * When an audit log is rotated, the actual rotation must be performed @@ -121,7 +123,7 @@ * by the worker thread so a waiting thread can start another replacement. * We also store a credential to perform audit log write operations with. */ -static wait_queue_t audit_replacement_wait_queue; +static struct cv audit_replacement_cv; static int audit_replacement_flag; static struct vnode *audit_replacement_vp; @@ -133,12 +135,6 @@ const static int audit_open_flags = FWRITE | O_APPEND; const static int audit_close_flags = FWRITE | O_APPEND; -/* - * XXX: Couldn't find the include file for this, so copied kern_exec.c's - * behavior. - */ -// extern task_t kernel_task; - static void audit_free(struct kaudit_record *ar) { @@ -213,11 +209,11 @@ } static void -audit_worker(void) +audit_worker(void *arg) { int do_replacement_signal, error, release_funnel; TAILQ_HEAD(, kaudit_record) ar_worklist; - struct kaudit_record *ar, *ar_start, *ar_stop; + struct kaudit_record *ar; struct vnode *audit_vp, *old_vp; struct ucred *audit_cred, *old_cred; struct thread *audit_td; @@ -237,7 +233,7 @@ thread_funnel_set(kernel_flock, FALSE); #endif - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); while (1) { /* * First priority: replace the audit log target if requested. @@ -263,12 +259,8 @@ audit_enabled = (audit_vp != NULL); if (old_vp != NULL || audit_vp != NULL) { - mutex_unlock(audit_mtx); -#ifdef DARWIN_FOO - thread_funnel_set(kernel_flock, TRUE); -#else + mtx_unlock(&audit_mtx); mtx_lock(&Giant); -#endif release_funnel = 1; } else release_funnel = 0; @@ -288,12 +280,8 @@ AUDIT_PRINTF(("Opening new audit file\n")); } if (release_funnel) { -#ifdef DARWIN_FOO - thread_funnel_set(kernel_flock, FALSE); -#else mtx_unlock(&Giant); -#endif - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); } do_replacement_signal = 1; } @@ -306,29 +294,18 @@ * successfully. */ if (do_replacement_signal) - wait_queue_wakeup_all(audit_replacement_wait_queue, - 0, THREAD_AWAKENED); + cv_broadcast(&audit_replacement_cv); /* * Next, check to see if we have any records to drain into * the vnode. If not, go back to waiting for an event. */ if (TAILQ_EMPTY(&audit_q)) { - int ret; - AUDIT_PRINTF(("audit_worker waiting\n")); - ret = wait_queue_assert_wait(audit_wait_queue, 0, - THREAD_UNINT); - mutex_unlock(audit_mtx); - - assert(ret == THREAD_WAITING); - ret = thread_block(THREAD_CONTINUE_NULL); - assert(ret == THREAD_AWAKENED); + cv_wait(&audit_cv, &audit_mtx); AUDIT_PRINTF(("audit_worker woken up\n")); AUDIT_PRINTF(("audit_worker: new vp = %p; value of flag %d\n", audit_replacement_vp, audit_replacement_flag)); - - mutex_lock(audit_mtx); continue; } @@ -350,12 +327,12 @@ TAILQ_REMOVE(&audit_q, ar, k_q); TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q); } - mutex_unlock(audit_mtx); + mtx_unlock(&audit_mtx); while ((ar = TAILQ_FIRST(&ar_worklist))) { TAILQ_REMOVE(&ar_worklist, ar, k_q); audit_free(ar); } - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); continue; } @@ -375,7 +352,7 @@ TAILQ_REMOVE(&audit_q, ar, k_q); TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q); } - mutex_unlock(audit_mtx); + mtx_unlock(&audit_mtx); release_funnel = 0; while ((ar = TAILQ_FIRST(&ar_worklist))) { TAILQ_REMOVE(&ar_worklist, ar, k_q); @@ -403,27 +380,26 @@ audit_free(ar); } if (release_funnel) -#ifdef DARWIN_FOO - thread_funnel_set(kernel_flock, FALSE); -#else mtx_unlock(&Giant); -#endif - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); } } void audit_init(void) { + int error; /* Verify that the syscall to audit event table is the same * size as the system call table. */ +#ifdef DARWIN_FOO if (nsys_au_event != nsysent) { printf("Security auditing service initialization failed, "); printf("audit event table doesn't match syscall table.\n"); return; } +#endif printf("Security auditing service present\n"); TAILQ_INIT(&audit_q); @@ -432,41 +408,34 @@ audit_replacement_cred = NULL; audit_replacement_flag = 0; audit_replacement_vp = NULL; - audit_mtx = mutex_alloc(ETAP_NO_TRACE); - audit_wait_queue = wait_queue_alloc(SYNC_POLICY_FIFO); - audit_replacement_wait_queue = wait_queue_alloc(SYNC_POLICY_FIFO); + mtx_init(&audit_mtx, "audit_mtx", NULL, MTX_DEF); + cv_init(&audit_cv, "audit_cv"); + cv_init(&audit_replacement_cv, "audit_replacement_cv"); /* Initialize the BSM audit subsystem. */ kau_init(); - kernel_thread(kernel_task, audit_worker); + error = kthread_create(audit_worker, NULL, &audit_thread, 0, 0, + "audit_worker"); + if (error != 0) + panic("audit_init: kthread_create returned %d", error); } static void audit_rotate_vnode(struct ucred *cred, struct vnode *vp) { - int ret; /* * If other parallel log replacements have been requested, we wait * until they've finished before continuing. */ - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); while (audit_replacement_flag != 0) { - AUDIT_PRINTF(("audit_rotate_vnode: sleeping to wait for " "flag\n")); - ret = wait_queue_assert_wait(audit_replacement_wait_queue, 0, - THREAD_UNINT); - mutex_unlock(audit_mtx); - - assert(ret == THREAD_WAITING); - ret = thread_block(THREAD_CONTINUE_NULL); - assert(ret == THREAD_AWAKENED); + cv_wait(&audit_replacement_cv, &audit_mtx); AUDIT_PRINTF(("audit_rotate_vnode: woken up (flag %d)\n", audit_replacement_flag)); - - mutex_lock(audit_mtx); } audit_replacement_cred = cred; audit_replacement_flag = 1; @@ -476,7 +445,7 @@ * Wake up the audit worker to perform the exchange once we * release the mutex. */ - wait_queue_wakeup_one(audit_wait_queue, 0, THREAD_AWAKENED); + cv_signal(&audit_cv); /* * Wait for the audit_worker to broadcast that a replacement has @@ -485,15 +454,10 @@ */ AUDIT_PRINTF(("audit_rotate_vnode: waiting for news of " "replacement\n")); - ret = wait_queue_assert_wait(audit_replacement_wait_queue, 0, - THREAD_UNINT); - mutex_unlock(audit_mtx); - - assert(ret == THREAD_WAITING); - ret = thread_block(THREAD_CONTINUE_NULL); - assert(ret == THREAD_AWAKENED); + cv_wait(&audit_replacement_cv, &audit_mtx); AUDIT_PRINTF(("audit_rotate_vnode: change acknowledged by " "audit_worker (flag " "now %d)\n", audit_replacement_flag)); + mtx_unlock(&audit_mtx); } /* @@ -529,7 +493,6 @@ int audit(struct thread *td, struct audit_args *uap) { - register struct pcred *pc = p->p_cred; int error; void * rec; struct kaudit_record *ar; @@ -542,7 +505,7 @@ if (ar == NULL) return (ENOTSUP); - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); @@ -579,19 +542,13 @@ /* * System call to manipulate auditing. */ -struct auditon_args { - int cmd; - void * data; - int length; -}; /* ARGSUSED */ int auditon(struct thread *td, struct auditon_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); return (ENOSYS); @@ -600,18 +557,13 @@ /* * System call to pass in file descriptor for audit log. */ -struct auditsvc_args { - int fd; - int limit; -}; /* ARGSUSED */ int auditsvc(struct thread *td, struct auditsvc_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); return (ENOSYS); @@ -621,17 +573,13 @@ * System calls to manage the user audit information. * XXXAUDIT May need to lock the proc structure. */ -struct getauid_args { - au_id_t *auid; -}; /* ARGSUSED */ int getauid(struct thread *td, struct getauid_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); @@ -643,17 +591,13 @@ return (0); } -struct setauid_args { - au_id_t *auid; -}; /* ARGSUSED */ int setauid(struct thread *td, struct setauid_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); @@ -669,17 +613,13 @@ /* * System calls to get and set process audit information. */ -struct getaudit_args { - struct auditinfo *auditinfo; -}; /* ARGSUSED */ int getaudit(struct thread *td, struct getaudit_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); error = copyout((void *)p->p_au, (void *)uap->auditinfo, @@ -690,17 +630,13 @@ return (0); } -struct setaudit_args { - struct auditinfo *auditinfo; -}; /* ARGSUSED */ int setaudit(struct thread *td, struct setaudit_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); error = copyin((void *)uap->auditinfo, (void *)p->p_au, @@ -711,35 +647,25 @@ return (0); } -struct getaudit_addr_args { - struct auditinfo_addr *auditinfo_addr; - int length; -}; /* ARGSUSED */ int getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); return (ENOSYS); } -struct setaudit_addr_args { - struct auditinfo_addr *auditinfo_addr; - int length; -}; /* ARGSUSED */ int setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) { - register struct pcred *pc = p->p_cred; int error; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); return (ENOSYS); @@ -750,20 +676,16 @@ * * XXX: Should generate an audit event. */ -struct auditctl_args { - char *path; -}; /* ARGSUSED */ int auditctl(struct thread *td, struct auditctl_args *uap) { - struct kaudit_record *ar; struct nameidata nd; struct ucred *cred; struct vnode *vp; - int error, flags, ret; + int error, flags; - error = suser(p->p_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); @@ -779,17 +701,17 @@ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p); flags = audit_open_flags; - error = vn_open(&nd, flags, 0); + error = vn_open(&nd, &flags, 0, -1); if (error) goto out; VOP_UNLOCK(nd.ni_vp, 0, p); vp = nd.ni_vp; if (vp->v_type != VREG) { - vn_close(vp, audit_close_flags, p->p_ucred, p); + vn_close(vp, audit_close_flags, td->td_ucred, p); error = EINVAL; goto out; } - cred = p->p_ucred; + cred = td->td_ucred; crhold(cred); } @@ -806,7 +728,7 @@ * MPSAFE */ struct kaudit_record * -audit_new(int event, struct proc *p, struct uthread *uthread) +audit_new(int event, struct proc *p, struct thread *td) { struct kaudit_record *ar; int no_record; @@ -822,9 +744,9 @@ #if 0 if (event != AUDIT_EVENT_FILESTOP && event != AUDIT_EVENT_FILESTART) { #endif - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); no_record = (audit_suspended || !audit_enabled); - mutex_unlock(audit_mtx); + mtx_unlock(&audit_mtx); if (no_record) return (NULL); #if 0 @@ -858,11 +780,11 @@ /* Export the subject credential. */ cru2x(p->p_ucred, &ar->k_ar.ar_subj_cred); - ar->k_ar.ar_subj_ruid = p->p_cred->p_ruid; - ar->k_ar.ar_subj_rgid = p->p_cred->p_rgid; - ar->k_ar.ar_subj_egid = p->p_ucred->cr_groups[0]; + 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]; ar->k_ar.ar_subj_auid = p->p_au->ai_auid; - ar->k_ar.ar_subj_pid = p->p_pid; + ar->k_ar.ar_subj_pid = td->td_proc->p_pid; bcopy(p->p_comm, ar->k_ar.ar_subj_comm, MAXCOMLEN); bcopy(&p->p_au->ai_mask, &ar->k_ar.ar_subj_amask, sizeof(p->p_au->ai_mask)); @@ -913,19 +835,19 @@ * size bound (perhaps configurable), and if that bound is reached, * threads should sleep in audit_commit() until there's room. */ - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); /* * Note: it could be that some records initiated while audit was * enabled should still be committed? */ if (audit_suspended || !audit_enabled) { - mutex_unlock(audit_mtx); + mtx_unlock(&audit_mtx); audit_free(ar); return; } TAILQ_INSERT_TAIL(&audit_q, ar, k_q); - wait_queue_wakeup_one(audit_wait_queue, 0, THREAD_AWAKENED); - mutex_unlock(audit_mtx); + cv_signal(&audit_cv); + mtx_unlock(&audit_mtx); } /* @@ -934,11 +856,11 @@ */ void audit_syscall_enter(unsigned short code, struct proc *proc, - struct uthread *uthread) + struct thread *td) { int audit_event; - assert(uthread->uu_ar == NULL); + KASSERT(td->td_ar == NULL, ("audit_syscall_enter: td->td_ar != NULL")); audit_event = sys_au_event[code]; @@ -953,15 +875,15 @@ #endif if (au_preselect(audit_event, &proc->p_au->ai_mask, AU_PRS_FAILURE | AU_PRS_SUCCESS)) { - uthread->uu_ar = audit_new(audit_event, proc, uthread); + td->td_ar = audit_new(audit_event, proc, td); } else { - uthread->uu_ar = NULL; + td->td_ar = NULL; } } } void -audit_syscall_exit(int error, struct proc *proc, struct uthread *uthread) +audit_syscall_exit(int error, struct proc *proc, struct thread *td) { int retval; @@ -976,12 +898,12 @@ if (error) retval = -1; else - retval = uthread->uu_rval[0]; + retval = td->td_retval[0]; - audit_commit(uthread->uu_ar, error, retval); - if (uthread->uu_ar != NULL) + audit_commit(td->td_ar, error, retval); + if (td->td_ar != NULL) AUDIT_PRINTF(("audit record committed by pid %d\n", proc->p_pid)); - uthread->uu_ar = NULL; + td->td_ar = NULL; } @@ -1396,7 +1318,7 @@ if (p == NULL || upath == NULL) return; /* nothing to do! */ - if (flags & (ARG_UPATH1 | ARG_UPATH2) == 0) + if ((flags & (ARG_UPATH1 | ARG_UPATH2)) == 0) return; ar = currecord(); @@ -1449,7 +1371,7 @@ int len; char **pathp; struct vnode_au_info *vnp; - struct proc *p; + struct thread *td; if (vp == NULL) return; @@ -1458,10 +1380,10 @@ if (ar == NULL) /* This will be the case for unaudited system calls */ return; - if (flags & (ARG_VNODE1 | ARG_VNODE2) == 0) + if ((flags & (ARG_VNODE1 | ARG_VNODE2)) == 0) return; - p = current_proc(); + td = curthread; if (flags & ARG_VNODE1) { ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_KPATH1); @@ -1494,7 +1416,7 @@ * XXX: We'd assert the vnode lock here, only Darwin doesn't * appear to have vnode locking assertions. */ - error = VOP_GETATTR(vp, &vattr, p->p_ucred, p); + error = VOP_GETATTR(vp, &vattr, td->td_ucred, td); if (error) { /* XXX: How to handle this case? */ return; ==== //depot/projects/trustedbsd/audit2/sys/security/audit/kern_audit.h#4 (text+ko) ==== @@ -193,11 +193,11 @@ void audit_shutdown(void); struct kaudit_record *audit_new(int event, struct proc *p, - struct uthread *uthread); + struct thread *td); -void audit_syscall_enter(unsigned short code, struct proc *proc, struct uthread *uthread); +void audit_syscall_enter(unsigned short code, struct proc *proc, struct thread *td); void audit_syscall_exit(int error, struct proc *proc, - struct uthread *uthread); + struct thread *td); int kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau);