PERFORCE change 56726 for review
Wayne Salamon
wsalamon at FreeBSD.org
Thu Jul 8 02:31:03 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=56726
Change 56726 by wsalamon at 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 <bsm/audit.h>
@@ -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 <bsm/audit_kernel.h>
/*
* 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 <sys/param.h>
+#include <sys/condvar.h>
#include <sys/file.h>
+#include <sys/filedesc.h>
#include <sys/fcntl.h>
+#include <sys/ipc.h>
#include <sys/kernel.h>
-#include <sys/lock.h>
+#include <sys/kthread.h>
+#include <sys/malloc.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/sysproto.h>
#include <sys/systm.h>
-#include <sys/time.h>
#include <sys/ucred.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
-#include <sys/user.h>
-#include <sys/syscall.h>
-#include <sys/malloc.h>
-#include <sys/un.h>
+
#include <netinet/in.h>
-#include <sys/socketvar.h>
-#include <sys/protosw.h>
-#include <sys/domain.h>
-#include <sys/mount.h>
-#include <net/route.h>
#include <netinet/in_pcb.h>
#include <bsm/audit.h>
#include <bsm/audit_kevents.h>
+#include <bsm/audit_kernel.h>
#include <security/audit/audit_klib.h>
-#include <bsm/audit_kernel.h>
+
+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) <<<
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list