svn commit: r316450 - in head/sys: conf security/audit

Robert Watson rwatson at FreeBSD.org
Mon Apr 3 10:16:00 UTC 2017


Author: rwatson
Date: Mon Apr  3 10:15:58 2017
New Revision: 316450
URL: https://svnweb.freebsd.org/changeset/base/316450

Log:
  Break audit_bsm_klib.c into two files: one (audit_bsm_klib.c)
  retaining various utility functions used during BSM generation,
  and a second (audit_bsm_db.c) that contains the various in-kernel
  databases supporting various audit activities (the class and
  event-name tables).
  
  (No functional change is intended.)
  
  Obtained from:	TrustedBSD Project
  MFC after:	3 weeks
  Sponsored by:	DARPA, AFRL

Added:
  head/sys/security/audit/audit_bsm_db.c
     - copied, changed from r316446, head/sys/security/audit/audit_bsm_klib.c
Modified:
  head/sys/conf/files
  head/sys/security/audit/audit_bsm_klib.c

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Mon Apr  3 09:41:43 2017	(r316449)
+++ head/sys/conf/files	Mon Apr  3 10:15:58 2017	(r316450)
@@ -4595,6 +4595,7 @@ rpc/rpcsec_gss/svc_rpcsec_gss.c	optional
 security/audit/audit.c		optional audit
 security/audit/audit_arg.c	optional audit
 security/audit/audit_bsm.c	optional audit
+security/audit/audit_bsm_db.c	optional audit
 security/audit/audit_bsm_klib.c	optional audit
 security/audit/audit_dtrace.c	optional dtaudit audit | dtraceall audit compile-with "${CDDL_C}"
 security/audit/audit_pipe.c	optional audit

Copied and modified: head/sys/security/audit/audit_bsm_db.c (from r316446, head/sys/security/audit/audit_bsm_klib.c)
==============================================================================
--- head/sys/security/audit/audit_bsm_klib.c	Mon Apr  3 08:50:54 2017	(r316446, copy source)
+++ head/sys/security/audit/audit_bsm_db.c	Mon Apr  3 10:15:58 2017	(r316450)
@@ -106,64 +106,6 @@ static struct evname_list	evnamemap_hash
 #define	EVNAMEMAP_WLOCK()	sx_xlock(&evnamemap_lock)
 #define	EVNAMEMAP_WUNLOCK()	sx_xunlock(&evnamemap_lock)
 
-struct aue_open_event {
-	int		aoe_flags;
-	au_event_t	aoe_event;
-};
-
-static const struct aue_open_event aue_open[] = {
-	{ O_RDONLY,					AUE_OPEN_R },
-	{ (O_RDONLY | O_CREAT),				AUE_OPEN_RC },
-	{ (O_RDONLY | O_CREAT | O_TRUNC),		AUE_OPEN_RTC },
-	{ (O_RDONLY | O_TRUNC),				AUE_OPEN_RT },
-	{ O_RDWR,					AUE_OPEN_RW },
-	{ (O_RDWR | O_CREAT),				AUE_OPEN_RWC },
-	{ (O_RDWR | O_CREAT | O_TRUNC),			AUE_OPEN_RWTC },
-	{ (O_RDWR | O_TRUNC),				AUE_OPEN_RWT },
-	{ O_WRONLY,					AUE_OPEN_W },
-	{ (O_WRONLY | O_CREAT),				AUE_OPEN_WC },
-	{ (O_WRONLY | O_CREAT | O_TRUNC),		AUE_OPEN_WTC },
-	{ (O_WRONLY | O_TRUNC),				AUE_OPEN_WT },
-};
-
-static const struct aue_open_event aue_openat[] = {
-	{ O_RDONLY,					AUE_OPENAT_R },
-	{ (O_RDONLY | O_CREAT),				AUE_OPENAT_RC },
-	{ (O_RDONLY | O_CREAT | O_TRUNC),		AUE_OPENAT_RTC },
-	{ (O_RDONLY | O_TRUNC),				AUE_OPENAT_RT },
-	{ O_RDWR,					AUE_OPENAT_RW },
-	{ (O_RDWR | O_CREAT),				AUE_OPENAT_RWC },
-	{ (O_RDWR | O_CREAT | O_TRUNC),			AUE_OPENAT_RWTC },
-	{ (O_RDWR | O_TRUNC),				AUE_OPENAT_RWT },
-	{ O_WRONLY,					AUE_OPENAT_W },
-	{ (O_WRONLY | O_CREAT),				AUE_OPENAT_WC },
-	{ (O_WRONLY | O_CREAT | O_TRUNC),		AUE_OPENAT_WTC },
-	{ (O_WRONLY | O_TRUNC),				AUE_OPENAT_WT },
-};
-
-static const int aue_msgsys[] = {
-	/* 0 */ AUE_MSGCTL,
-	/* 1 */ AUE_MSGGET,
-	/* 2 */ AUE_MSGSND,
-	/* 3 */ AUE_MSGRCV,
-};
-static const int aue_msgsys_count = sizeof(aue_msgsys) / sizeof(int);
-
-static const int aue_semsys[] = {
-	/* 0 */ AUE_SEMCTL,
-	/* 1 */ AUE_SEMGET,
-	/* 2 */ AUE_SEMOP,
-};
-static const int aue_semsys_count = sizeof(aue_semsys) / sizeof(int);
-
-static const int aue_shmsys[] = {
-	/* 0 */ AUE_SHMAT,
-	/* 1 */ AUE_SHMDT,
-	/* 2 */ AUE_SHMGET,
-	/* 3 */ AUE_SHMCTL,
-};
-static const int aue_shmsys_count = sizeof(aue_shmsys) / sizeof(int);
-
 /*
  * Look up the class for an audit event in the class mapping table.
  */
@@ -248,33 +190,6 @@ au_evclassmap_init(void)
 }
 
 /*
- * Check whether an event is aditable by comparing the mask of classes this
- * event is part of against the given mask.
- */
-int
-au_preselect(au_event_t event, au_class_t class, au_mask_t *mask_p, int sorf)
-{
-	au_class_t effmask = 0;
-
-	if (mask_p == NULL)
-		return (-1);
-
-	/*
-	 * Perform the actual check of the masks against the event.
-	 */
-	if (sorf & AU_PRS_SUCCESS)
-		effmask |= (mask_p->am_success & class);
-
-	if (sorf & AU_PRS_FAILURE)
-		effmask |= (mask_p->am_failure & class);
-
-	if (effmask)
-		return (1);
-	else
-		return (0);
-}
-
-/*
  * Look up the name for an audit event in the event-to-name mapping table.
  */
 int
@@ -413,389 +328,3 @@ out:
 	return (ene);
 }
 #endif /* !KDTRACE_HOOKS */
-
-/*
- * Convert sysctl names and present arguments to events.
- */
-au_event_t
-audit_ctlname_to_sysctlevent(int name[], uint64_t valid_arg)
-{
-
-	/* can't parse it - so return the worst case */
-	if ((valid_arg & (ARG_CTLNAME | ARG_LEN)) != (ARG_CTLNAME | ARG_LEN))
-		return (AUE_SYSCTL);
-
-	switch (name[0]) {
-	/* non-admin "lookups" treat them special */
-	case KERN_OSTYPE:
-	case KERN_OSRELEASE:
-	case KERN_OSREV:
-	case KERN_VERSION:
-	case KERN_ARGMAX:
-	case KERN_CLOCKRATE:
-	case KERN_BOOTTIME:
-	case KERN_POSIX1:
-	case KERN_NGROUPS:
-	case KERN_JOB_CONTROL:
-	case KERN_SAVED_IDS:
-	case KERN_OSRELDATE:
-	case KERN_DUMMY:
-		return (AUE_SYSCTL_NONADMIN);
-
-	/* only treat the changeable controls as admin */
-	case KERN_MAXVNODES:
-	case KERN_MAXPROC:
-	case KERN_MAXFILES:
-	case KERN_MAXPROCPERUID:
-	case KERN_MAXFILESPERPROC:
-	case KERN_HOSTID:
-	case KERN_SECURELVL:
-	case KERN_HOSTNAME:
-	case KERN_VNODE:
-	case KERN_PROC:
-	case KERN_FILE:
-	case KERN_PROF:
-	case KERN_NISDOMAINNAME:
-	case KERN_UPDATEINTERVAL:
-	case KERN_NTP_PLL:
-	case KERN_BOOTFILE:
-	case KERN_DUMPDEV:
-	case KERN_IPC:
-	case KERN_PS_STRINGS:
-	case KERN_USRSTACK:
-	case KERN_LOGSIGEXIT:
-	case KERN_IOV_MAX:
-		return ((valid_arg & ARG_VALUE) ?
-		    AUE_SYSCTL : AUE_SYSCTL_NONADMIN);
-
-	default:
-		return (AUE_SYSCTL);
-	}
-	/* NOTREACHED */
-}
-
-/*
- * Convert an open flags specifier into a specific type of open event for
- * auditing purposes.
- */
-au_event_t
-audit_flags_and_error_to_openevent(int oflags, int error)
-{
-	int i;
-
-	/*
-	 * Need to check only those flags we care about.
-	 */
-	oflags = oflags & (O_RDONLY | O_CREAT | O_TRUNC | O_RDWR | O_WRONLY);
-	for (i = 0; i < nitems(aue_open); i++) {
-		if (aue_open[i].aoe_flags == oflags)
-			return (aue_open[i].aoe_event);
-	}
-	return (AUE_OPEN);
-}
-
-au_event_t
-audit_flags_and_error_to_openatevent(int oflags, int error)
-{
-	int i;
-
-	/*
-	 * Need to check only those flags we care about.
-	 */
-	oflags = oflags & (O_RDONLY | O_CREAT | O_TRUNC | O_RDWR | O_WRONLY);
-	for (i = 0; i < nitems(aue_openat); i++) {
-		if (aue_openat[i].aoe_flags == oflags)
-			return (aue_openat[i].aoe_event);
-	}
-	return (AUE_OPENAT);
-}
-
-/*
- * Convert a MSGCTL command to a specific event.
- */
-au_event_t
-audit_msgctl_to_event(int cmd)
-{
-
-	switch (cmd) {
-	case IPC_RMID:
-		return (AUE_MSGCTL_RMID);
-
-	case IPC_SET:
-		return (AUE_MSGCTL_SET);
-
-	case IPC_STAT:
-		return (AUE_MSGCTL_STAT);
-
-	default:
-		/* We will audit a bad command. */
-		return (AUE_MSGCTL);
-	}
-}
-
-/*
- * Convert a SEMCTL command to a specific event.
- */
-au_event_t
-audit_semctl_to_event(int cmd)
-{
-
-	switch (cmd) {
-	case GETALL:
-		return (AUE_SEMCTL_GETALL);
-
-	case GETNCNT:
-		return (AUE_SEMCTL_GETNCNT);
-
-	case GETPID:
-		return (AUE_SEMCTL_GETPID);
-
-	case GETVAL:
-		return (AUE_SEMCTL_GETVAL);
-
-	case GETZCNT:
-		return (AUE_SEMCTL_GETZCNT);
-
-	case IPC_RMID:
-		return (AUE_SEMCTL_RMID);
-
-	case IPC_SET:
-		return (AUE_SEMCTL_SET);
-
-	case SETALL:
-		return (AUE_SEMCTL_SETALL);
-
-	case SETVAL:
-		return (AUE_SEMCTL_SETVAL);
-
-	case IPC_STAT:
-		return (AUE_SEMCTL_STAT);
-
-	default:
-		/* We will audit a bad command. */
-		return (AUE_SEMCTL);
-	}
-}
-
-/*
- * Convert msgsys(2), semsys(2), and shmsys(2) system-call variations into
- * audit events, if possible.
- */
-au_event_t
-audit_msgsys_to_event(int which)
-{
-
-	if ((which >= 0) && (which < aue_msgsys_count))
-		return (aue_msgsys[which]);
-
-	/* Audit a bad command. */
-	return (AUE_MSGSYS);
-}
-
-au_event_t
-audit_semsys_to_event(int which)
-{
-
-	if ((which >= 0) && (which < aue_semsys_count))
-		return (aue_semsys[which]);
-
-	/* Audit a bad command. */
-	return (AUE_SEMSYS);
-}
-
-au_event_t
-audit_shmsys_to_event(int which)
-{
-
-	if ((which >= 0) && (which < aue_shmsys_count))
-		return (aue_shmsys[which]);
-
-	/* Audit a bad command. */
-	return (AUE_SHMSYS);
-}
-
-/*
- * Convert a command for the auditon() system call to a audit event.
- */
-au_event_t
-auditon_command_event(int cmd)
-{
-
-	switch(cmd) {
-	case A_GETPOLICY:
-		return (AUE_AUDITON_GPOLICY);
-
-	case A_SETPOLICY:
-		return (AUE_AUDITON_SPOLICY);
-
-	case A_GETKMASK:
-		return (AUE_AUDITON_GETKMASK);
-
-	case A_SETKMASK:
-		return (AUE_AUDITON_SETKMASK);
-
-	case A_GETQCTRL:
-		return (AUE_AUDITON_GQCTRL);
-
-	case A_SETQCTRL:
-		return (AUE_AUDITON_SQCTRL);
-
-	case A_GETCWD:
-		return (AUE_AUDITON_GETCWD);
-
-	case A_GETCAR:
-		return (AUE_AUDITON_GETCAR);
-
-	case A_GETSTAT:
-		return (AUE_AUDITON_GETSTAT);
-
-	case A_SETSTAT:
-		return (AUE_AUDITON_SETSTAT);
-
-	case A_SETUMASK:
-		return (AUE_AUDITON_SETUMASK);
-
-	case A_SETSMASK:
-		return (AUE_AUDITON_SETSMASK);
-
-	case A_GETCOND:
-		return (AUE_AUDITON_GETCOND);
-
-	case A_SETCOND:
-		return (AUE_AUDITON_SETCOND);
-
-	case A_GETCLASS:
-		return (AUE_AUDITON_GETCLASS);
-
-	case A_SETCLASS:
-		return (AUE_AUDITON_SETCLASS);
-
-	case A_GETPINFO:
-	case A_SETPMASK:
-	case A_SETFSIZE:
-	case A_GETFSIZE:
-	case A_GETPINFO_ADDR:
-	case A_GETKAUDIT:
-	case A_SETKAUDIT:
-	default:
-		return (AUE_AUDITON);	/* No special record */
-	}
-}
-
-/*
- * Create a canonical path from given path by prefixing either the root
- * directory, or the current working directory.  If the process working
- * directory is NULL, we could use 'rootvnode' to obtain the root directory,
- * but this results in a volfs name written to the audit log. So we will
- * leave the filename starting with '/' in the audit log in this case.
- */
-void
-audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath)
-{
-	struct vnode *cvnp, *rvnp;
-	char *rbuf, *fbuf, *copy;
-	struct filedesc *fdp;
-	struct sbuf sbf;
-	cap_rights_t rights;
-	int error, needslash;
-
-	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "%s: at %s:%d",
-	    __func__,  __FILE__, __LINE__);
-
-	copy = path;
-	rvnp = cvnp = NULL;
-	fdp = td->td_proc->p_fd;
-	FILEDESC_SLOCK(fdp);
-	/*
-	 * Make sure that we handle the chroot(2) case.  If there is an
-	 * alternate root directory, prepend it to the audited pathname.
-	 */
-	if (fdp->fd_rdir != NULL && fdp->fd_rdir != rootvnode) {
-		rvnp = fdp->fd_rdir;
-		vhold(rvnp);
-	}
-	/*
-	 * If the supplied path is relative, make sure we capture the current
-	 * working directory so we can prepend it to the supplied relative
-	 * path.
-	 */
-	if (*path != '/') {
-		if (dirfd == AT_FDCWD) {
-			cvnp = fdp->fd_cdir;
-			vhold(cvnp);
-		} else {
-			/* XXX: fgetvp() that vhold()s vnode instead of vref()ing it would be better */
-			error = fgetvp(td, dirfd, cap_rights_init(&rights), &cvnp);
-			if (error) {
-				FILEDESC_SUNLOCK(fdp);
-				cpath[0] = '\0';
-				if (rvnp != NULL)
-					vdrop(rvnp);
-				return;
-			}
-			vhold(cvnp);
-			vrele(cvnp);
-		}
-		needslash = (fdp->fd_rdir != cvnp);
-	} else {
-		needslash = 1;
-	}
-	FILEDESC_SUNLOCK(fdp);
-	/*
-	 * NB: We require that the supplied array be at least MAXPATHLEN bytes
-	 * long.  If this is not the case, then we can run into serious trouble.
-	 */
-	(void) sbuf_new(&sbf, cpath, MAXPATHLEN, SBUF_FIXEDLEN);
-	/*
-	 * Strip leading forward slashes.
-	 */
-	while (*copy == '/')
-		copy++;
-	/*
-	 * Make sure we handle chroot(2) and prepend the global path to these
-	 * environments.
-	 *
-	 * NB: vn_fullpath(9) on FreeBSD is less reliable than vn_getpath(9)
-	 * on Darwin.  As a result, this may need some additional attention
-	 * in the future.
-	 */
-	if (rvnp != NULL) {
-		error = vn_fullpath_global(td, rvnp, &rbuf, &fbuf);
-		vdrop(rvnp);
-		if (error) {
-			cpath[0] = '\0';
-			if (cvnp != NULL)
-				vdrop(cvnp);
-			return;
-		}
-		(void) sbuf_cat(&sbf, rbuf);
-		free(fbuf, M_TEMP);
-	}
-	if (cvnp != NULL) {
-		error = vn_fullpath(td, cvnp, &rbuf, &fbuf);
-		vdrop(cvnp);
-		if (error) {
-			cpath[0] = '\0';
-			return;
-		}
-		(void) sbuf_cat(&sbf, rbuf);
-		free(fbuf, M_TEMP);
-	}
-	if (needslash)
-		(void) sbuf_putc(&sbf, '/');
-	/*
-	 * Now that we have processed any alternate root and relative path
-	 * names, add the supplied pathname.
-	 */
-        (void) sbuf_cat(&sbf, copy);
-	/*
-	 * One or more of the previous sbuf operations could have resulted in
-	 * the supplied buffer being overflowed.  Check to see if this is the
-	 * case.
-	 */
-	if (sbuf_error(&sbf) != 0) {
-		cpath[0] = '\0';
-		return;
-	}
-	sbuf_finish(&sbf);
-}

Modified: head/sys/security/audit/audit_bsm_klib.c
==============================================================================
--- head/sys/security/audit/audit_bsm_klib.c	Mon Apr  3 09:41:43 2017	(r316449)
+++ head/sys/security/audit/audit_bsm_klib.c	Mon Apr  3 10:15:58 2017	(r316450)
@@ -58,54 +58,6 @@ __FBSDID("$FreeBSD$");
 #include <security/audit/audit.h>
 #include <security/audit/audit_private.h>
 
-/*
- * Hash table functions for the audit event number to event class mask
- * mapping.
- */
-#define	EVCLASSMAP_HASH_TABLE_SIZE	251
-struct evclass_elem {
-	au_event_t event;
-	au_class_t class;
-	LIST_ENTRY(evclass_elem) entry;
-};
-struct evclass_list {
-	LIST_HEAD(, evclass_elem) head;
-};
-
-static MALLOC_DEFINE(M_AUDITEVCLASS, "audit_evclass", "Audit event class");
-static struct rwlock		evclass_lock;
-static struct evclass_list	evclass_hash[EVCLASSMAP_HASH_TABLE_SIZE];
-
-#define	EVCLASS_LOCK_INIT()	rw_init(&evclass_lock, "evclass_lock")
-#define	EVCLASS_RLOCK()		rw_rlock(&evclass_lock)
-#define	EVCLASS_RUNLOCK()	rw_runlock(&evclass_lock)
-#define	EVCLASS_WLOCK()		rw_wlock(&evclass_lock)
-#define	EVCLASS_WUNLOCK()	rw_wunlock(&evclass_lock)
-
-/*
- * Hash table maintaining a mapping from audit event numbers to audit event
- * names.  For now, used only by DTrace, but present always so that userspace
- * tools can register and inspect fields consistently even if DTrace is not
- * present.
- *
- * struct evname_elem is defined in audit_private.h so that audit_dtrace.c can
- * use the definition.
- */
-#define	EVNAMEMAP_HASH_TABLE_SIZE	251
-struct evname_list {
-	LIST_HEAD(, evname_elem)	enl_head;
-};
-
-static MALLOC_DEFINE(M_AUDITEVNAME, "audit_evname", "Audit event name");
-static struct sx		evnamemap_lock;
-static struct evname_list	evnamemap_hash[EVNAMEMAP_HASH_TABLE_SIZE];
-
-#define	EVNAMEMAP_LOCK_INIT()	sx_init(&evnamemap_lock, "evnamemap_lock");
-#define	EVNAMEMAP_RLOCK()	sx_slock(&evnamemap_lock)
-#define	EVNAMEMAP_RUNLOCK()	sx_sunlock(&evnamemap_lock)
-#define	EVNAMEMAP_WLOCK()	sx_xlock(&evnamemap_lock)
-#define	EVNAMEMAP_WUNLOCK()	sx_xunlock(&evnamemap_lock)
-
 struct aue_open_event {
 	int		aoe_flags;
 	au_event_t	aoe_event;
@@ -165,89 +117,6 @@ static const int aue_shmsys[] = {
 static const int aue_shmsys_count = sizeof(aue_shmsys) / sizeof(int);
 
 /*
- * Look up the class for an audit event in the class mapping table.
- */
-au_class_t
-au_event_class(au_event_t event)
-{
-	struct evclass_list *evcl;
-	struct evclass_elem *evc;
-	au_class_t class;
-
-	EVCLASS_RLOCK();
-	evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE];
-	class = 0;
-	LIST_FOREACH(evc, &evcl->head, entry) {
-		if (evc->event == event) {
-			class = evc->class;
-			goto out;
-		}
-	}
-out:
-	EVCLASS_RUNLOCK();
-	return (class);
-}
-
-/*
- * Insert a event to class mapping. If the event already exists in the
- * mapping, then replace the mapping with the new one.
- *
- * XXX There is currently no constraints placed on the number of mappings.
- * May want to either limit to a number, or in terms of memory usage.
- */
-void
-au_evclassmap_insert(au_event_t event, au_class_t class)
-{
-	struct evclass_list *evcl;
-	struct evclass_elem *evc, *evc_new;
-
-	/*
-	 * Pessimistically, always allocate storage before acquiring mutex.
-	 * Free if there is already a mapping for this event.
-	 */
-	evc_new = malloc(sizeof(*evc), M_AUDITEVCLASS, M_WAITOK);
-
-	EVCLASS_WLOCK();
-	evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE];
-	LIST_FOREACH(evc, &evcl->head, entry) {
-		if (evc->event == event) {
-			evc->class = class;
-			EVCLASS_WUNLOCK();
-			free(evc_new, M_AUDITEVCLASS);
-			return;
-		}
-	}
-	evc = evc_new;
-	evc->event = event;
-	evc->class = class;
-	LIST_INSERT_HEAD(&evcl->head, evc, entry);
-	EVCLASS_WUNLOCK();
-}
-
-void
-au_evclassmap_init(void)
-{
-	int i;
-
-	EVCLASS_LOCK_INIT();
-	for (i = 0; i < EVCLASSMAP_HASH_TABLE_SIZE; i++)
-		LIST_INIT(&evclass_hash[i].head);
-
-	/*
-	 * Set up the initial event to class mapping for system calls.
-	 *
-	 * XXXRW: Really, this should walk all possible audit events, not all
-	 * native ABI system calls, as there may be audit events reachable
-	 * only through non-native system calls.  It also seems a shame to
-	 * frob the mutex this early.
-	 */
-	for (i = 0; i < SYS_MAXSYSCALL; i++) {
-		if (sysent[i].sy_auevent != AUE_NULL)
-			au_evclassmap_insert(sysent[i].sy_auevent, 0);
-	}
-}
-
-/*
  * Check whether an event is aditable by comparing the mask of classes this
  * event is part of against the given mask.
  */
@@ -275,146 +144,6 @@ au_preselect(au_event_t event, au_class_
 }
 
 /*
- * Look up the name for an audit event in the event-to-name mapping table.
- */
-int
-au_event_name(au_event_t event, char *name)
-{
-	struct evname_list *enl;
-	struct evname_elem *ene;
-	int error;
-
-	error = ENOENT;
-	EVNAMEMAP_RLOCK();
-	enl = &evnamemap_hash[event % EVNAMEMAP_HASH_TABLE_SIZE];
-	LIST_FOREACH(ene, &enl->enl_head, ene_entry) {
-		if (ene->ene_event == event) {
-			strlcpy(name, ene->ene_name, EVNAMEMAP_NAME_SIZE);
-			error = 0;
-			goto out;
-		}
-	}
-out:
-	EVNAMEMAP_RUNLOCK();
-	return (error);
-}
-
-/*
- * Insert a event-to-name mapping.  If the event already exists in the
- * mapping, then replace the mapping with the new one.
- *
- * XXX There is currently no constraints placed on the number of mappings.
- * May want to either limit to a number, or in terms of memory usage.
- *
- * XXXRW: Accepts truncated name -- but perhaps should return failure instead?
- *
- * XXXRW: It could be we need a way to remove existing names...?
- *
- * XXXRW: We handle collisions between numbers, but I wonder if we also need a
- * way to handle name collisions, for DTrace, where probe names must be
- * unique?
- */
-void
-au_evnamemap_insert(au_event_t event, const char *name)
-{
-	struct evname_list *enl;
-	struct evname_elem *ene, *ene_new;
-
-	/*
-	 * Pessimistically, always allocate storage before acquiring lock.
-	 * Free if there is already a mapping for this event.
-	 */
-	ene_new = malloc(sizeof(*ene_new), M_AUDITEVNAME, M_WAITOK | M_ZERO);
-	EVNAMEMAP_WLOCK();
-	enl = &evnamemap_hash[event % EVNAMEMAP_HASH_TABLE_SIZE];
-	LIST_FOREACH(ene, &enl->enl_head, ene_entry) {
-		if (ene->ene_event == event) {
-			EVNAME_LOCK(ene);
-			(void)strlcpy(ene->ene_name, name,
-			    sizeof(ene->ene_name));
-			EVNAME_UNLOCK(ene);
-			EVNAMEMAP_WUNLOCK();
-			free(ene_new, M_AUDITEVNAME);
-			return;
-		}
-	}
-	ene = ene_new;
-	mtx_init(&ene->ene_lock, "au_evnamemap", NULL, MTX_DEF);
-	ene->ene_event = event;
-	(void)strlcpy(ene->ene_name, name, sizeof(ene->ene_name));
-	LIST_INSERT_HEAD(&enl->enl_head, ene, ene_entry);
-	EVNAMEMAP_WUNLOCK();
-}
-
-void
-au_evnamemap_init(void)
-{
-	int i;
-
-	EVNAMEMAP_LOCK_INIT();
-	for (i = 0; i < EVNAMEMAP_HASH_TABLE_SIZE; i++)
-		LIST_INIT(&evnamemap_hash[i].enl_head);
-
-	/*
-	 * XXXRW: Unlike the event-to-class mapping, we don't attempt to
-	 * pre-populate the list.  Perhaps we should...?  But not sure we
-	 * really want to duplicate /etc/security/audit_event in the kernel
-	 * -- and we'd need a way to remove names?
-	 */
-}
-
-/*
- * The DTrace audit provider occasionally needs to walk the entries in the
- * event-to-name mapping table, and uses this public interface to do so.  A
- * write lock is acquired so that the provider can safely update its fields in
- * table entries.
- */
-void
-au_evnamemap_foreach(au_evnamemap_callback_t callback)
-{
-	struct evname_list *enl;
-	struct evname_elem *ene;
-	int i;
-
-	EVNAMEMAP_WLOCK();
-	for (i = 0; i < EVNAMEMAP_HASH_TABLE_SIZE; i++) {
-		enl = &evnamemap_hash[i];
-		LIST_FOREACH(ene, &enl->enl_head, ene_entry)
-			callback(ene);
-	}
-	EVNAMEMAP_WUNLOCK();
-}
-
-#ifdef KDTRACE_HOOKS
-/*
- * Look up an event-to-name mapping table entry by event number.  As evname
- * elements are stable in memory, we can return the pointer without the table
- * lock held -- but the caller will need to lock the element mutex before
- * accessing element fields.
- *
- * NB: the event identifier in elements is stable and can be read without
- * holding the evname_elem lock.
- */
-struct evname_elem *
-au_evnamemap_lookup(au_event_t event)
-{
-	struct evname_list *enl;
-	struct evname_elem *ene;
-
-	EVNAMEMAP_RLOCK();
-	enl = &evnamemap_hash[event % EVNAMEMAP_HASH_TABLE_SIZE];
-	LIST_FOREACH(ene, &enl->enl_head, ene_entry) {
-		if (ene->ene_event == event)
-			goto out;
-	}
-	ene = NULL;
-out:
-	EVNAMEMAP_RUNLOCK();
-	return (ene);
-}
-#endif /* !KDTRACE_HOOKS */
-
-/*
  * Convert sysctl names and present arguments to events.
  */
 au_event_t


More information about the svn-src-head mailing list