From owner-p4-projects@FreeBSD.ORG Thu Jul 8 02:31:04 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0CBE516A4D0; Thu, 8 Jul 2004 02:31:04 +0000 (GMT) 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 DB8A216A4CE for ; Thu, 8 Jul 2004 02:31:03 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D0E2E43D1F for ; Thu, 8 Jul 2004 02:31:03 +0000 (GMT) (envelope-from wsalamon@computer.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i682V3N6092194 for ; Thu, 8 Jul 2004 02:31:03 GMT (envelope-from wsalamon@computer.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i682V3vE092191 for perforce@freebsd.org; Thu, 8 Jul 2004 02:31:03 GMT (envelope-from wsalamon@computer.org) Date: Thu, 8 Jul 2004 02:31:03 GMT Message-Id: <200407080231.i682V3vE092191@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to wsalamon@computer.org using -f From: Wayne Salamon To: Perforce Change Reviews Subject: PERFORCE change 56726 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: Thu, 08 Jul 2004 02:31:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=56726 Change 56726 by wsalamon@wsalamon_epi on 2004/07/08 02:31:00 Changes necessary to create a successful compilation. Still need to merge in some changes from the audit2 project. Affected files ... .. //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#2 edit .. //depot/projects/trustedbsd/audit3/sys/bsm/audit_kernel.h#2 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_klib.h#2 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/kern_audit.c#3 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/kern_bsm_audit.c#3 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/kern_bsm_klib.c#3 edit .. //depot/projects/trustedbsd/audit3/sys/security/audit/kern_bsm_token.c#3 edit .. //depot/projects/trustedbsd/audit3/sys/sys/sysproto.h#2 edit Differences ... ==== //depot/projects/trustedbsd/audit3/sys/bsm/audit.h#2 (text+ko) ==== @@ -162,13 +162,13 @@ typedef u_int32_t au_class_t; struct au_tid { - dev_t port; + udev_t port; u_int32_t machine; }; typedef struct au_tid au_tid_t; struct au_tid_addr { - dev_t at_port; + udev_t at_port; u_int32_t at_type; u_int32_t at_addr[4]; }; @@ -284,7 +284,7 @@ }; typedef struct au_evclass_map au_evclass_map_t; -#ifndef KERNEL +#ifndef _KERNEL int audit (const void *, int); int auditon (int, void *, int); @@ -295,7 +295,7 @@ int setaudit (const struct auditinfo *); int getaudit_addr (struct auditinfo_addr *, int); int setaudit_addr (const struct auditinfo_addr *, int); -#endif /* !KERNEL */ +#endif /* !_KERNEL */ __END_DECLS ==== //depot/projects/trustedbsd/audit3/sys/bsm/audit_kernel.h#2 (text+ko) ==== @@ -24,7 +24,7 @@ #ifndef _BSM_AUDIT_KERNEL_H #define _BSM_AUDIT_KERNEL_H -#ifdef KERNEL +#ifdef _KERNEL #include @@ -98,6 +98,10 @@ #define ARG_NONE 0x0000000000000000ULL #define ARG_ALL 0xFFFFFFFFFFFFFFFFULL +#ifdef MALLOC_DECLARE +MALLOC_DECLARE(M_AUDIT); +#endif + /* Defines for the kernel audit record k_ar_commit field */ #define AR_COMMIT_KERNEL 0x00000001U #define AR_COMMIT_USER 0x00000010U @@ -106,7 +110,7 @@ mode_t vn_mode; uid_t vn_uid; gid_t vn_gid; - dev_t vn_dev; + udev_t vn_dev; long vn_fsid; long vn_fileid; long vn_gen; @@ -211,8 +215,6 @@ int ar_arg_svipc_id; void * ar_arg_svipc_addr; struct posix_ipc_perm ar_arg_pipc_perm; - mach_port_t ar_arg_mach_port1; - mach_port_t ar_arg_mach_port2; union auditon_udata ar_arg_auditon; }; @@ -240,16 +242,11 @@ void audit_init(void); void audit_shutdown(void); -struct kaudit_record *audit_new(int event, struct proc *p, - struct uthread *uthread); +struct kaudit_record *audit_new(int event, struct thread *td); void audit_syscall_enter(unsigned short code, - struct proc *proc, struct uthread *uthread); -void audit_syscall_exit(int error, struct proc *proc, - struct uthread *uthread); -void audit_mach_syscall_enter(unsigned short audit_event); -void audit_mach_syscall_exit(int retval, - struct uthread *uthread); + struct thread *td); +void audit_syscall_exit(int error, struct thread *td); int kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau); @@ -261,7 +258,7 @@ */ struct au_record *kau_open(void); int kau_write(struct au_record *rec, token_t *m); -int kau_close(struct au_record *rec, +void kau_close(struct au_record *rec, struct timespec *endtime, short event); void kau_free(struct au_record *rec); void kau_init(void); @@ -299,11 +296,11 @@ void audit_arg_signum(u_int signum); void audit_arg_socket(int sodomain, int sotype, int soprotocol); -void audit_arg_sockaddr(struct proc *p, +void audit_arg_sockaddr(struct thread *td, struct sockaddr *so); void audit_arg_auid(uid_t auid); void audit_arg_auditinfo(struct auditinfo *au_info); -void audit_arg_upath(struct proc *p, char *upath, +void audit_arg_upath(struct thread *td, char *upath, u_int64_t flags); void audit_arg_vnpath(struct vnode *vp, u_int64_t flags); void audit_arg_text(char *text); @@ -316,11 +313,11 @@ mode_t mode); void audit_arg_auditon(union auditon_udata *udata); void audit_arg_file(struct proc *p, struct file *fp); -void audit_arg_mach_port1(mach_port_t port); -void audit_arg_mach_port2(mach_port_t port); void audit_sysclose(struct proc *p, 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); @@ -395,6 +392,6 @@ #endif /* AUDIT */ -#endif /* KERNEL */ +#endif /* _KERNEL */ #endif /* !_BSM_AUDIT_KERNEL_H */ ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_klib.h#2 (text+ko) ==== @@ -28,7 +28,7 @@ #define AU_PRS_FAILURE 2 #define AU_PRS_BOTH (AU_PRS_SUCCESS|AU_PRS_FAILURE) -#ifdef KERNEL +#ifdef _KERNEL #include /* * Some of the BSM tokenizer functions take different parameters in the @@ -40,17 +40,21 @@ token_t *kau_to_attr64(struct vnode_au_info *vni); int au_preselect(au_event_t event, au_mask_t *mask_p, int sorf); au_event_t flags_and_error_to_openevent(int oflags, int error); -void au_evclassmap_init(); +void au_evclassmap_init(void); void au_evclassmap_insert(au_event_t event, au_class_t class); au_class_t au_event_class(au_event_t event); +au_event_t ctlname_to_sysctlevent(int name[], uint64_t valid_arg); +int auditon_command_event(int cmd); +int msgctl_to_event(int cmd); +int semctl_to_event(int cmr); -int canon_path(struct proc *p, char *path, char *cpath); +int canon_path(struct thread *td, char *path, char *cpath); /* * Define a system call to audit event mapping table. */ extern au_event_t sys_au_event[]; extern int nsys_au_event; /* number of entries in this table */ -#endif /*KERNEL*/ +#endif /* _KERNEL */ #endif /* ! _BSM_AUDIT_KLIB_H_ */ ==== //depot/projects/trustedbsd/audit3/sys/security/audit/kern_audit.c#3 (text+ko) ==== @@ -21,35 +21,38 @@ */ #include +#include #include +#include #include +#include #include -#include +#include +#include #include #include #include +#include +#include +#include +#include +#include #include -#include #include #include +#include #include #include -#include -#include -#include -#include + #include -#include -#include -#include -#include -#include #include #include #include +#include #include -#include + +MALLOC_DEFINE(M_AUDIT, "audit", "Audit event records"); #ifdef AUDIT @@ -89,7 +92,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 @@ -103,16 +106,17 @@ static int audit_q_len; static int audit_pre_q_len; -static wait_queue_t audit_wait_queue; -static zone_t audit_zone; - /* * Condition variable to signal to the worker that it has work to do: * either new records are in the queue, or a log replacement is taking * place. */ -static int audit_worker_event; -#define AUDIT_WORKER_EVENT ((event_t)&audit_worker_event) +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 @@ -128,20 +132,25 @@ * 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 int audit_replacement_event; -#define AUDIT_REPLACEMENT_EVENT ((event_t)&audit_replacement_event) +static struct cv audit_replacement_cv; static int audit_replacement_flag; static struct vnode *audit_replacement_vp; static struct ucred *audit_replacement_cred; /* - * Wait queue for auditing threads that cannot commit the audit - * record at the present time. Also, the queue control parameter - * structure. + * Condition variable to signal to the worker that it has work to do: + * either new records are in the queue, or a log replacement is taking + * place. + */ +static struct cv audit_commit_cv; + +/* + * Condition variable for auditing threads wait on when in fail-stop mode. + * Threads wait on this CV forever (and ever), never seeing the light of + * day again. */ -static int audit_commit_event; -#define AUDIT_COMMIT_EVENT ((event_t)&audit_commit_event) +static struct cv audit_fail_cv; static struct au_qctrl audit_qctrl; @@ -161,10 +170,10 @@ */ static struct au_mask audit_nae_mask; -/* +/* * Flags related to Kernel->user-space communication. */ -static int audit_file_rotate_wait; +static int audit_file_rotate_wait; /* * Flags controlling behavior in low storage situations. @@ -176,61 +185,49 @@ static int audit_fail_stop; static int audit_in_failure; -/* - * When in a fail-stop mode, threads will drop into this wait queue - * rather than perform auditable events. They won't ever get woken - * up. - */ -static int audit_failure_event; -#define AUDIT_FAILURE_EVENT ((event_t)&audit_failure_event) - -/* - * 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) { if (ar->k_ar.ar_arg_upath1 != NULL) { - kfree((vm_offset_t)ar->k_ar.ar_arg_upath1, MAXPATHLEN); + free(ar->k_ar.ar_arg_upath1, M_AUDIT); } if (ar->k_ar.ar_arg_upath2 != NULL) { - kfree((vm_offset_t)ar->k_ar.ar_arg_upath2, MAXPATHLEN); + free(ar->k_ar.ar_arg_upath2, M_AUDIT); } if (ar->k_ar.ar_arg_kpath1 != NULL) { - kfree((vm_offset_t)ar->k_ar.ar_arg_kpath1, MAXPATHLEN); + free(ar->k_ar.ar_arg_kpath1, M_AUDIT); } if (ar->k_ar.ar_arg_kpath2 != NULL) { - kfree((vm_offset_t)ar->k_ar.ar_arg_kpath2, MAXPATHLEN); + free(ar->k_ar.ar_arg_kpath2, M_AUDIT); } if (ar->k_ar.ar_arg_text != NULL) { - kfree((vm_offset_t)ar->k_ar.ar_arg_text, MAXPATHLEN); + free(ar->k_ar.ar_arg_text, M_AUDIT); } if (ar->k_udata != NULL) { - kfree((vm_offset_t)ar->k_udata, (vm_size_t)ar->k_ulen); + free(ar->k_udata, M_AUDIT); } - zfree(audit_zone, (vm_offset_t)ar); + free(ar, M_AUDIT); } static int audit_write(struct vnode *vp, struct kaudit_record *ar, struct ucred *cred, - struct proc *p) + struct thread *td) { - struct statfs *mnt_stat = &vp->v_mount->mnt_stat; int ret; struct au_record *bsm; - struct vattr vattr; - mach_port_t audit_port; + mtx_assert(&Giant, MA_OWNED); /* * First, gather statistics on the audit log file and file system * so that we know how we're doing on space. In both cases, * if we're unable to perform the operation, we drop the record * and return. However, this is arguably an assertion failure. + * XXX Need a FreeBSD equivalent. */ +#if DARWIN_FOO + struct vattr vattr; + struct statfs *mnt_stat = &vp->v_mount->mnt_stat; ret = VFS_STATFS(vp->v_mount, mnt_stat, p); if (ret) goto out; @@ -314,6 +311,7 @@ audit_in_failure = 1; } +#endif /* * If there is a user audit record attached to the kernel record, * then write the user record. @@ -326,7 +324,8 @@ */ if (ar->k_ar_commit & AR_COMMIT_USER) { ret = vn_rdwr(UIO_WRITE, vp, (void *)ar->k_udata, ar->k_ulen, - (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, p); + (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, + NULL, td); if (ret) goto out; } @@ -356,18 +355,21 @@ goto out; } - /* XXX This function can be called with the kernel funnel held, + /* + * XXX + * This function must be called with Giant held, * which is not optimal. We should break the write functionality * away from the BSM record generation and have the BSM generation * done before this function is called. This function will then * take the BSM record as a parameter. */ ret = (vn_rdwr(UIO_WRITE, vp, (void *)bsm->data, bsm->len, - (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, p)); + (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, NULL, td)); kau_free(bsm); out: +#if DARWIN_FOO /* * When we're done processing the current record, we have to * check to see if we're in a failure mode, and if so, whether @@ -381,40 +383,38 @@ VOP_UNLOCK(vp, 0, p); panic("Audit store overflow; record queue drained."); } +#endif return (ret); } static void -audit_worker() +audit_worker(void *arg) { - int do_replacement_signal, error, release_funnel; + int do_replacement_signal, error, release_giant; 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 proc *audit_p; + struct thread *audit_td; AUDIT_PRINTF(("audit_worker starting\n")); + /* + * These are thread-local variables requiring no synchronization. + */ TAILQ_INIT(&ar_worklist); audit_cred = NULL; - audit_p = current_proc(); + audit_td = curthread; audit_vp = NULL; - /* - * XXX: Presumably we can assume Mach threads are started without - * holding the BSD kernel funnel? - */ - thread_funnel_set(kernel_flock, FALSE); - - mutex_lock(audit_mtx); + mtx_lock(&audit_mtx); while (1) { /* * First priority: replace the audit log target if requested. * As we actually close the vnode in the worker thread, we - * need to grab the funnel, which means releasing audit_mtx. + * need to grab Giant, which means releasing audit_mtx. * In case another replacement was scheduled while the mutex * we released, we loop. * @@ -435,18 +435,18 @@ audit_enabled = (audit_vp != NULL); if (old_vp != NULL || audit_vp != NULL) { - mutex_unlock(audit_mtx); - thread_funnel_set(kernel_flock, TRUE); - release_funnel = 1; + mtx_unlock(&audit_mtx); + mtx_lock(&Giant); + release_giant = 1; } else - release_funnel = 0; + release_giant = 0; /* * XXX: What to do about write failures here? */ if (old_vp != NULL) { AUDIT_PRINTF(("Closing old audit file\n")); vn_close(old_vp, audit_close_flags, old_cred, - audit_p); + audit_td); crfree(old_cred); old_cred = NULL; old_vp = NULL; @@ -455,9 +455,9 @@ if (audit_vp != NULL) { AUDIT_PRINTF(("Opening new audit file\n")); } - if (release_funnel) { - thread_funnel_set(kernel_flock, FALSE); - mutex_lock(audit_mtx); + if (release_giant) { + mtx_unlock(&Giant); + mtx_lock(&audit_mtx); } do_replacement_signal = 1; } @@ -470,29 +470,18 @@ * successfully. */ if (do_replacement_signal) - wait_queue_wakeup_all(audit_wait_queue, - AUDIT_REPLACEMENT_EVENT, 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, - AUDIT_WORKER_EVENT, - 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; } @@ -506,7 +495,7 @@ * * XXX: We go out of our way to avoid calling audit_free() * with the audit_mtx held, to avoid a lock order reversal - * as free() may grab the funnel. This will be fixed at + * as free() may grab Giant. This should be fixed at * some point. */ if (audit_vp == NULL) { @@ -514,24 +503,21 @@ TAILQ_REMOVE(&audit_q, ar, k_q); audit_q_len--; if (audit_q_len <= audit_qctrl.aq_lowater) - wait_queue_wakeup_one( - audit_wait_queue, - AUDIT_COMMIT_EVENT, - THREAD_AWAKENED); + cv_broadcast(&audit_commit_cv); 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; } /* - * We have both records to write, and an active vnode + * We have both records to write and an active vnode * to write to. Dequeue a record, and start the write. * Eventually, it might make sense to dequeue several * records and perform our own clustering, if the lower @@ -539,22 +525,20 @@ * * XXX: We go out of our way to avoid calling audit_free() * with the audit_mtx held, to avoid a lock order reversal - * as free() may grab the funnel. This will be fixed at + * as free() may grab Giant. This should be fixed at * some point. */ while ((ar = TAILQ_FIRST(&audit_q))) { TAILQ_REMOVE(&audit_q, ar, k_q); audit_q_len--; - if (audit_q_len <= audit_qctrl.aq_lowater) { - wait_queue_wakeup_one(audit_wait_queue, - AUDIT_COMMIT_EVENT, THREAD_AWAKENED); - } + if (audit_q_len <= audit_qctrl.aq_lowater) + cv_broadcast(&audit_commit_cv); TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q); } - mutex_unlock(audit_mtx); - release_funnel = 0; + mtx_unlock(&audit_mtx); + release_giant = 0; while ((ar = TAILQ_FIRST(&ar_worklist))) { TAILQ_REMOVE(&ar_worklist, ar, k_q); if (audit_vp != NULL) { @@ -562,14 +546,14 @@ * XXX: What should happen if there's a write * error here? */ - if (!release_funnel) { - thread_funnel_set(kernel_flock, TRUE); - release_funnel = 1; + if (!release_giant) { + mtx_lock(&Giant); + release_giant = 1; } - VOP_LEASE(audit_vp, audit_p, audit_cred, + VOP_LEASE(audit_vp, audit_td, audit_cred, LEASE_WRITE); error = audit_write(audit_vp, ar, audit_cred, - audit_p); + audit_td); if (error && audit_panic_on_write_fail) panic("audit_worker: write error %d\n", error); @@ -579,28 +563,32 @@ } audit_free(ar); } - if (release_funnel) - thread_funnel_set(kernel_flock, FALSE); - mutex_lock(audit_mtx); + if (release_giant) + mtx_unlock(&Giant); + 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); audit_q_len = 0; + audit_pre_q_len = 0; audit_enabled = 0; audit_suspended = 0; audit_replacement_cred = NULL; @@ -614,45 +602,36 @@ audit_qctrl.aq_bufsz = AQ_BUFSZ; audit_qctrl.aq_minfree = AU_FS_MINFREE; - audit_mtx = mutex_alloc(ETAP_NO_TRACE); - audit_wait_queue = wait_queue_alloc(SYNC_POLICY_FIFO); - audit_zone = zinit(sizeof(struct kaudit_record), - AQ_HIWATER*sizeof(struct kaudit_record), - 8192, - "audit_zone"); + mtx_init(&audit_mtx, "audit_mtx", NULL, MTX_DEF); + cv_init(&audit_cv, "audit_cv"); + cv_init(&audit_replacement_cv, "audit_replacement_cv"); + cv_init(&audit_commit_cv, "audit_commit_cv"); + cv_init(&audit_fail_cv, "audit_fail_cv"); /* Initialize the BSM audit subsystem. */ kau_init(); - kernel_thread(kernel_task, audit_worker); + error = kthread_create(audit_worker, NULL, &audit_thread, RFHIGHPID, + 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_wait_queue, - AUDIT_REPLACEMENT_EVENT, - 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_flag)); } audit_replacement_cred = cred; audit_replacement_flag = 1; @@ -662,7 +641,7 @@ * Wake up the audit worker to perform the exchange once we * release the mutex. */ - wait_queue_wakeup_one(audit_wait_queue, AUDIT_WORKER_EVENT, THREAD_AWAKENED); + cv_signal(&audit_cv); /* * Wait for the audit_worker to broadcast that a replacement has @@ -671,17 +650,14 @@ */ AUDIT_PRINTF(("audit_rotate_vnode: waiting for news of " "replacement\n")); - ret = wait_queue_assert_wait(audit_wait_queue, - AUDIT_REPLACEMENT_EVENT, - 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); + /* XXX Need to figure out how the kernel->userspace file full + * signalling will take place. + */ audit_file_rotate_wait = 0; /* We can now request another rotation */ } @@ -694,22 +670,18 @@ audit_rotate_vnode(NULL, NULL); } -static __inline__ struct uthread * -curuthread(void) -{ - return (get_bsdthread_info(current_act())); -} - static __inline__ struct kaudit_record * currecord(void) { - return (curuthread()->uu_ar); + return (curthread->td_ar); } /********************************** * Begin system calls. * **********************************/ /* + * MPSAFE + * * System call to allow a user space application to submit a BSM audit * record to the kernel for inclusion in the audit log. This function * does little verification on the audit record that is submitted. @@ -718,21 +690,15 @@ * work, since we pre-select only based on the AUE_audit event type, * not the event type submitted as part of the user audit data. */ -struct audit_args { - void * record; - int length; -}; /* ARGSUSED */ int -audit(struct proc *p, struct audit_args *uap, register_t *retval) +audit(struct thread *td, struct audit_args *uap) { - register struct pcred *pc = p->p_cred; int error; void * rec; struct kaudit_record *ar; - struct uthread *uthr; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); @@ -745,24 +711,21 @@ * commit the user audit record. */ if (ar == NULL) { - uthr = curuthread(); - if (uthr == NULL) /* can this happen? */ - return (ENOTSUP); /* This is not very efficient; we're required to allocate * a complete kernel audit record just so the user record * can tag along. */ - uthr->uu_ar = audit_new(AUE_NULL, p, uthr); - if (uthr->uu_ar == NULL) /* auditing not on, or memory error */ + td->td_ar = audit_new(AUE_NULL, td); + if (td->td_ar == NULL) /*auditing not on, or memory error */ return (ENOTSUP); - ar = uthr->uu_ar; + ar = td->td_ar; } if (uap->length > MAX_AUDIT_RECORD_SIZE) return (EINVAL); - rec = (void *)kalloc((vm_size_t)uap->length); + rec = malloc(uap->length, M_AUDIT, M_WAITOK); error = copyin(uap->record, rec, uap->length); if (error) @@ -779,40 +742,36 @@ * record along with the record for this audit event. */ ar->k_udata = rec; + ar->k_ulen = uap->length; ar->k_ar_commit |= AR_COMMIT_USER; - ar->k_ulen = uap->length; return (0); free_out: /* audit_syscall_exit() will free the audit record on the thread * even if we allocated it above. */ - kfree((vm_offset_t)rec, (vm_size_t)uap->length); + free(rec, M_AUDIT); return (error); } /* + * MPSAFE + * * System call to manipulate auditing. */ -struct auditon_args { - int cmd; - void * data; - int length; -}; /* ARGSUSED */ int -auditon(struct proc *p, struct auditon_args *uap, register_t *retval) +auditon(struct thread *td, struct auditon_args *uap) { - register struct pcred *pc = p->p_cred; - int ret; + int error; int len; union auditon_udata udata; struct proc *tp; AUDIT_ARG(cmd, uap->cmd); - ret = suser(pc->pc_ucred, &p->p_acflag); - if (ret) - return (ret); + error = suser(td); + if (error) + return (error); len = uap->length; if ((len <= 0) || (len > sizeof(union auditon_udata))) @@ -836,9 +795,9 @@ case A_GETCLASS: case A_GETPINFO: case A_GETPINFO_ADDR: - ret = copyin(uap->data, (void *)&udata, uap->length); - if (ret) - return (ret); + error = copyin(uap->data, (void *)&udata, uap->length); + if (error) + return (error); AUDIT_ARG(auditon, &udata); break; } @@ -987,9 +946,9 @@ case A_GETFSIZE: case A_GETPINFO_ADDR: case A_GETKAUDIT: - ret = copyout((void *)&udata, uap->data, uap->length); - if (ret) - return (ret); + error = copyout((void *)&udata, uap->data, uap->length); + if (error) + return (error); break; } @@ -997,159 +956,149 @@ } /* + * MPSAFE + * * 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 proc *p, struct getauid_args *uap, register_t *retval) +getauid(struct thread *td, struct getauid_args *uap) { - register struct pcred *pc = p->p_cred; int error; + au_id_t id; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); - error = copyout((void *)&p->p_au->ai_auid, (void *)uap->auid, - sizeof(*uap->auid)); - if (error) - return (error); - - return (0); + /* + * 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)); } -struct setauid_args { - au_id_t *auid; -}; +/* MPSAFE */ /* ARGSUSED */ int -setauid(struct proc *p, struct setauid_args *uap, register_t *retval) +setauid(struct thread *td, struct setauid_args *uap) { - register struct pcred *pc = p->p_cred; int error; + au_id_t id; - error = suser(pc->pc_ucred, &p->p_acflag); + error = suser(td); if (error) return (error); - error = copyin((void *)uap->auid, (void *)&p->p_au->ai_auid, - sizeof(p->p_au->ai_auid)); + error = copyin(uap->auid, &id, sizeof(id)); if (error) return (error); >>> TRUNCATED FOR MAIL (1000 lines) <<<