Date: Mon, 3 Apr 2017 10:15:58 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r316450 - in head/sys: conf security/audit Message-ID: <201704031015.v33AFwL9014939@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704031015.v33AFwL9014939>