X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d9a64523371fa019c4575bb400cbbc3a50ac9903..HEAD:/bsd/security/audit/audit_bsd.c diff --git a/bsd/security/audit/audit_bsd.c b/bsd/security/audit/audit_bsd.c index 5a6ea3750..2f3adbace 100644 --- a/bsd/security/audit/audit_bsd.c +++ b/bsd/security/audit/audit_bsd.c @@ -50,6 +50,7 @@ #include #include #include +#include #include @@ -57,35 +58,35 @@ extern void ipc_port_release_send(ipc_port_t port); #if CONFIG_AUDIT struct mhdr { - size_t mh_size; - au_malloc_type_t *mh_type; - u_long mh_magic; - char mh_data[0]; + size_t mh_size; + au_malloc_type_t *mh_type; + u_long mh_magic; + char mh_data[0]; }; /* - * The lock group for the audit subsystem. + * The lock group for the audit subsystem. */ -static lck_grp_t *audit_lck_grp = NULL; +static LCK_GRP_DECLARE(audit_lck_grp, "Audit"); -#define AUDIT_MHMAGIC 0x4D656C53 +#define AUDIT_MHMAGIC 0x4D656C53 #if AUDIT_MALLOC_DEBUG -#define AU_MAX_SHORTDESC 20 -#define AU_MAX_LASTCALLER 20 +#define AU_MAX_SHORTDESC 20 +#define AU_MAX_LASTCALLER 20 struct au_malloc_debug_info { - SInt64 md_size; - SInt64 md_maxsize; - SInt32 md_inuse; - SInt32 md_maxused; - unsigned md_type; - unsigned md_magic; - char md_shortdesc[AU_MAX_SHORTDESC]; - char md_lastcaller[AU_MAX_LASTCALLER]; + SInt64 md_size; + SInt64 md_maxsize; + SInt32 md_inuse; + SInt32 md_maxused; + unsigned md_type; + unsigned md_magic; + char md_shortdesc[AU_MAX_SHORTDESC]; + char md_lastcaller[AU_MAX_LASTCALLER]; }; typedef struct au_malloc_debug_info au_malloc_debug_info_t; -au_malloc_type_t *audit_malloc_types[NUM_MALLOC_TYPES]; +au_malloc_type_t *audit_malloc_types[NUM_MALLOC_TYPES]; static int audit_sysctl_malloc_debug(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); @@ -94,11 +95,11 @@ SYSCTL_PROC(_kern, OID_AUTO, audit_malloc_debug, CTLFLAG_RD, NULL, 0, audit_sysctl_malloc_debug, "S,audit_malloc_debug", "Current malloc debug info for auditing."); -#define AU_MALLOC_DBINFO_SZ \ +#define AU_MALLOC_DBINFO_SZ \ (NUM_MALLOC_TYPES * sizeof(au_malloc_debug_info_t)) /* - * Copy out the malloc debug info via the sysctl interface. The userland code + * Copy out the malloc debug info via the sysctl interface. The userland code * is something like the following: * * error = sysctlbyname("kern.audit_malloc_debug", buffer_ptr, &buffer_len, @@ -116,35 +117,38 @@ audit_sysctl_malloc_debug(__unused struct sysctl_oid *oidp, __unused void *arg1, /* * This provides a read-only node. */ - if (req->newptr != USER_ADDR_NULL) - return (EPERM); + if (req->newptr != USER_ADDR_NULL) { + return EPERM; + } /* - * If just querying then return the space required. + * If just querying then return the space required. */ if (req->oldptr == USER_ADDR_NULL) { - req->oldidx = AU_MALLOC_DBINFO_SZ; - return (0); + req->oldidx = AU_MALLOC_DBINFO_SZ; + return 0; } /* * Alloc a temporary buffer. */ - if (req->oldlen < AU_MALLOC_DBINFO_SZ) - return (ENOMEM); - amdi_ptr = (au_malloc_debug_info_t *)kalloc(AU_MALLOC_DBINFO_SZ); - if (amdi_ptr == NULL) - return (ENOMEM); - bzero(amdi_ptr, AU_MALLOC_DBINFO_SZ); + if (req->oldlen < AU_MALLOC_DBINFO_SZ) { + return ENOMEM; + } + amdi_ptr = kheap_alloc(KHEAP_TEMP, AU_MALLOC_DBINFO_SZ, Z_WAITOK | Z_ZERO); + if (amdi_ptr == NULL) { + return ENOMEM; + } /* - * Build the record array. + * Build the record array. */ sz = 0; nxt_ptr = amdi_ptr; - for(i = 0; i < NUM_MALLOC_TYPES; i++) { - if (audit_malloc_types[i] == NULL) + for (i = 0; i < NUM_MALLOC_TYPES; i++) { + if (audit_malloc_types[i] == NULL) { continue; + } if (audit_malloc_types[i]->mt_magic != M_MAGIC) { nxt_ptr->md_magic = audit_malloc_types[i]->mt_magic; continue; @@ -157,22 +161,22 @@ audit_sysctl_malloc_debug(__unused struct sysctl_oid *oidp, __unused void *arg1, strlcpy(nxt_ptr->md_shortdesc, audit_malloc_types[i]->mt_shortdesc, AU_MAX_SHORTDESC - 1); strlcpy(nxt_ptr->md_lastcaller, - audit_malloc_types[i]->mt_lastcaller, AU_MAX_LASTCALLER-1); + audit_malloc_types[i]->mt_lastcaller, AU_MAX_LASTCALLER - 1); sz += sizeof(au_malloc_debug_info_t); nxt_ptr++; } req->oldlen = sz; err = SYSCTL_OUT(req, amdi_ptr, sz); - kfree(amdi_ptr, AU_MALLOC_DBINFO_SZ); + kheap_free(KHEAP_TEMP, amdi_ptr, AU_MALLOC_DBINFO_SZ); - return (err); + return err; } #endif /* AUDIT_MALLOC_DEBUG */ - + /* * BSD malloc() - * + * * If the M_NOWAIT flag is set then it may not block and return NULL. * If the M_ZERO flag is set then zero out the buffer. */ @@ -180,31 +184,25 @@ void * #if AUDIT_MALLOC_DEBUG _audit_malloc(size_t size, au_malloc_type_t *type, int flags, const char *fn) #else -_audit_malloc(size_t size, au_malloc_type_t *type, int flags) +_audit_malloc(size_t size, au_malloc_type_t * type, int flags) #endif { - struct mhdr *hdr; - size_t memsize; + struct mhdr *hdr; + size_t memsize; if (os_add_overflow(sizeof(*hdr), size, &memsize)) { - return (NULL); + return NULL; } - if (size == 0) - return (NULL); - if (flags & M_NOWAIT) { - hdr = (void *)kalloc_noblock(memsize); - } else { - hdr = (void *)kalloc(memsize); - if (hdr == NULL) - panic("_audit_malloc: kernel memory exhausted"); + if (size == 0) { + return NULL; + } + hdr = kheap_alloc(KHEAP_AUDIT, memsize, flags); + if (hdr == NULL) { + return NULL; } - if (hdr == NULL) - return (NULL); hdr->mh_size = memsize; hdr->mh_type = type; hdr->mh_magic = AUDIT_MHMAGIC; - if (flags & M_ZERO) - memset(hdr->mh_data, 0, size); #if AUDIT_MALLOC_DEBUG if (type != NULL && type->mt_type < NUM_MALLOC_TYPES) { OSAddAtomic64(memsize, &type->mt_size); @@ -215,7 +213,7 @@ _audit_malloc(size_t size, au_malloc_type_t *type, int flags) audit_malloc_types[type->mt_type] = type; } #endif /* AUDIT_MALLOC_DEBUG */ - return (hdr->mh_data); + return hdr->mh_data; } /* @@ -229,13 +227,14 @@ _audit_free(void *addr, __unused au_malloc_type_t *type) #endif { struct mhdr *hdr; - - if (addr == NULL) + + if (addr == NULL) { return; + } hdr = addr; hdr--; if (hdr->mh_magic != AUDIT_MHMAGIC) { - panic("_audit_free(): hdr->mh_magic (%lx) != AUDIT_MHMAGIC", hdr->mh_magic); + panic("_audit_free(): hdr->mh_magic (%lx) != AUDIT_MHMAGIC", hdr->mh_magic); } #if AUDIT_MALLOC_DEBUG @@ -244,7 +243,7 @@ _audit_free(void *addr, __unused au_malloc_type_t *type) OSAddAtomic(-1, &type->mt_inuse); } #endif /* AUDIT_MALLOC_DEBUG */ - kfree(hdr, hdr->mh_size); + kheap_free(KHEAP_AUDIT, hdr, hdr->mh_size); } /* @@ -253,11 +252,11 @@ _audit_free(void *addr, __unused au_malloc_type_t *type) void _audit_cv_init(struct cv *cvp, const char *desc) { - - if (desc == NULL) + if (desc == NULL) { cvp->cv_description = "UNKNOWN"; - else + } else { cvp->cv_description = desc; + } cvp->cv_waiters = 0; } @@ -267,7 +266,6 @@ _audit_cv_init(struct cv *cvp, const char *desc) void _audit_cv_destroy(struct cv *cvp) { - cvp->cv_description = NULL; cvp->cv_waiters = 0; } @@ -278,7 +276,6 @@ _audit_cv_destroy(struct cv *cvp) void _audit_cv_signal(struct cv *cvp) { - if (cvp->cv_waiters > 0) { wakeup_one((caddr_t)cvp); cvp->cv_waiters--; @@ -291,7 +288,6 @@ _audit_cv_signal(struct cv *cvp) void _audit_cv_broadcast(struct cv *cvp) { - if (cvp->cv_waiters > 0) { wakeup((caddr_t)cvp); cvp->cv_waiters = 0; @@ -306,7 +302,6 @@ _audit_cv_broadcast(struct cv *cvp) void _audit_cv_wait(struct cv *cvp, lck_mtx_t *mp, const char *desc) { - cvp->cv_waiters++; (void) msleep(cvp, mp, PZERO, desc, 0); } @@ -320,9 +315,8 @@ _audit_cv_wait(struct cv *cvp, lck_mtx_t *mp, const char *desc) int _audit_cv_wait_sig(struct cv *cvp, lck_mtx_t *mp, const char *desc) { - cvp->cv_waiters++; - return (msleep(cvp, mp, PSOCK | PCATCH, desc, 0)); + return msleep(cvp, mp, PSOCK | PCATCH, desc, 0); } /* @@ -335,20 +329,19 @@ _audit_mtx_init(struct mtx *mp, const char *lckname) _audit_mtx_init(struct mtx *mp, __unused const char *lckname) #endif { - mp->mtx_lock = lck_mtx_alloc_init(audit_lck_grp, LCK_ATTR_NULL); - KASSERT(mp->mtx_lock != NULL, + mp->mtx_lock = lck_mtx_alloc_init(&audit_lck_grp, LCK_ATTR_NULL); + KASSERT(mp->mtx_lock != NULL, ("_audit_mtx_init: Could not allocate a mutex.")); #if DIAGNOSTIC - strlcpy(mp->mtx_name, lckname, AU_MAX_LCK_NAME); + strlcpy(mp->mtx_name, lckname, AU_MAX_LCK_NAME); #endif } void _audit_mtx_destroy(struct mtx *mp) { - if (mp->mtx_lock) { - lck_mtx_free(mp->mtx_lock, audit_lck_grp); + lck_mtx_free(mp->mtx_lock, &audit_lck_grp); mp->mtx_lock = NULL; } } @@ -363,20 +356,19 @@ _audit_rw_init(struct rwlock *lp, const char *lckname) _audit_rw_init(struct rwlock *lp, __unused const char *lckname) #endif { - lp->rw_lock = lck_rw_alloc_init(audit_lck_grp, LCK_ATTR_NULL); - KASSERT(lp->rw_lock != NULL, + lp->rw_lock = lck_rw_alloc_init(&audit_lck_grp, LCK_ATTR_NULL); + KASSERT(lp->rw_lock != NULL, ("_audit_rw_init: Could not allocate a rw lock.")); #if DIAGNOSTIC - strlcpy(lp->rw_name, lckname, AU_MAX_LCK_NAME); + strlcpy(lp->rw_name, lckname, AU_MAX_LCK_NAME); #endif } void _audit_rw_destroy(struct rwlock *lp) { - if (lp->rw_lock) { - lck_rw_free(lp->rw_lock, audit_lck_grp); + lck_rw_free(lp->rw_lock, &audit_lck_grp); lp->rw_lock = NULL; } } @@ -403,7 +395,7 @@ _audit_cv_wait_continuation(struct cv *cvp, lck_mtx_t *mp, thread_continue_t fun } /* - * Simple recursive lock. + * Simple recursive lock. */ void #if DIAGNOSTIC @@ -412,12 +404,11 @@ _audit_rlck_init(struct rlck *lp, const char *lckname) _audit_rlck_init(struct rlck *lp, __unused const char *lckname) #endif { - - lp->rl_mtx = lck_mtx_alloc_init(audit_lck_grp, LCK_ATTR_NULL); - KASSERT(lp->rl_mtx != NULL, + lp->rl_mtx = lck_mtx_alloc_init(&audit_lck_grp, LCK_ATTR_NULL); + KASSERT(lp->rl_mtx != NULL, ("_audit_rlck_init: Could not allocate a recursive lock.")); #if DIAGNOSTIC - strlcpy(lp->rl_name, lckname, AU_MAX_LCK_NAME); + strlcpy(lp->rl_name, lckname, AU_MAX_LCK_NAME); #endif lp->rl_thread = 0; lp->rl_recurse = 0; @@ -425,11 +416,10 @@ _audit_rlck_init(struct rlck *lp, __unused const char *lckname) /* * Recursive lock. Allow same thread to recursively lock the same lock. - */ + */ void _audit_rlck_lock(struct rlck *lp) { - if (lp->rl_thread == current_thread()) { OSAddAtomic(1, &lp->rl_recurse); KASSERT(lp->rl_recurse < 10000, @@ -447,7 +437,7 @@ _audit_rlck_lock(struct rlck *lp) void _audit_rlck_unlock(struct rlck *lp) { - KASSERT(lp->rl_thread == current_thread(), + KASSERT(lp->rl_thread == current_thread(), ("_audit_rlck_unlock(): Don't own lock.")); /* Note: OSAddAtomic returns old value. */ @@ -456,13 +446,12 @@ _audit_rlck_unlock(struct rlck *lp) lck_mtx_unlock(lp->rl_mtx); } } - + void _audit_rlck_destroy(struct rlck *lp) { - if (lp->rl_mtx) { - lck_mtx_free(lp->rl_mtx, audit_lck_grp); + lck_mtx_free(lp->rl_mtx, &audit_lck_grp); lp->rl_mtx = NULL; } } @@ -474,13 +463,15 @@ void _audit_rlck_assert(struct rlck *lp, u_int assert) { thread_t cthd = current_thread(); - - if (assert == LCK_MTX_ASSERT_OWNED && lp->rl_thread == cthd) + + if (assert == LCK_MTX_ASSERT_OWNED && lp->rl_thread == cthd) { panic("recursive lock (%p) not held by this thread (%p).", lp, cthd); - if (assert == LCK_MTX_ASSERT_NOTOWNED && lp->rl_thread != 0) + } + if (assert == LCK_MTX_ASSERT_NOTOWNED && lp->rl_thread != 0) { panic("recursive lock (%p) held by thread (%p).", lp, cthd); + } } /* @@ -493,12 +484,11 @@ _audit_slck_init(struct slck *lp, const char *lckname) _audit_slck_init(struct slck *lp, __unused const char *lckname) #endif { - - lp->sl_mtx = lck_mtx_alloc_init(audit_lck_grp, LCK_ATTR_NULL); - KASSERT(lp->sl_mtx != NULL, + lp->sl_mtx = lck_mtx_alloc_init(&audit_lck_grp, LCK_ATTR_NULL); + KASSERT(lp->sl_mtx != NULL, ("_audit_slck_init: Could not allocate a sleep lock.")); #if DIAGNOSTIC - strlcpy(lp->sl_name, lckname, AU_MAX_LCK_NAME); + strlcpy(lp->sl_name, lckname, AU_MAX_LCK_NAME); #endif lp->sl_locked = 0; lp->sl_waiting = 0; @@ -506,7 +496,7 @@ _audit_slck_init(struct slck *lp, __unused const char *lckname) /* * Sleep lock lock. The 'intr' flag determines if the lock is interruptible. - * If 'intr' is true then signals or other events can interrupt the sleep lock. + * If 'intr' is true then signals or other events can interrupt the sleep lock. */ wait_result_t _audit_slck_lock(struct slck *lp, int intr) @@ -517,13 +507,14 @@ _audit_slck_lock(struct slck *lp, int intr) while (lp->sl_locked && res == THREAD_AWAKENED) { lp->sl_waiting = 1; res = lck_mtx_sleep(lp->sl_mtx, LCK_SLEEP_DEFAULT, - (event_t) lp, (intr) ? THREAD_INTERRUPTIBLE : THREAD_UNINT); + (event_t) lp, (intr) ? THREAD_INTERRUPTIBLE : THREAD_UNINT); } - if (res == THREAD_AWAKENED) + if (res == THREAD_AWAKENED) { lp->sl_locked = 1; + } lck_mtx_unlock(lp->sl_mtx); - - return (res); + + return res; } /* @@ -532,7 +523,6 @@ _audit_slck_lock(struct slck *lp, int intr) void _audit_slck_unlock(struct slck *lp) { - lck_mtx_lock(lp->sl_mtx); lp->sl_locked = 0; if (lp->sl_waiting) { @@ -545,7 +535,7 @@ _audit_slck_unlock(struct slck *lp) } /* - * Sleep lock try. Don't sleep if it doesn't get the lock. + * Sleep lock try. Don't sleep if it doesn't get the lock. */ int _audit_slck_trylock(struct slck *lp) @@ -554,11 +544,12 @@ _audit_slck_trylock(struct slck *lp) lck_mtx_lock(lp->sl_mtx); result = !lp->sl_locked; - if (result) + if (result) { lp->sl_locked = 1; + } lck_mtx_unlock(lp->sl_mtx); - return (result); + return result; } /* @@ -567,19 +558,19 @@ _audit_slck_trylock(struct slck *lp) void _audit_slck_assert(struct slck *lp, u_int assert) { - - if (assert == LCK_MTX_ASSERT_OWNED && lp->sl_locked == 0) + if (assert == LCK_MTX_ASSERT_OWNED && lp->sl_locked == 0) { panic("sleep lock (%p) not held.", lp); - if (assert == LCK_MTX_ASSERT_NOTOWNED && lp->sl_locked == 1) + } + if (assert == LCK_MTX_ASSERT_NOTOWNED && lp->sl_locked == 1) { panic("sleep lock (%p) held.", lp); + } } void _audit_slck_destroy(struct slck *lp) { - if (lp->sl_mtx) { - lck_mtx_free(lp->sl_mtx, audit_lck_grp); + lck_mtx_free(lp->sl_mtx, &audit_lck_grp); lp->sl_mtx = NULL; } } @@ -590,14 +581,14 @@ _audit_slck_destroy(struct slck *lp) */ #ifndef timersub #define timersub(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ - if ((vvp)->tv_usec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_usec += 1000000; \ - } \ - } while (0) + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) #endif /* @@ -626,44 +617,52 @@ _audit_ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) *lasttime = tv; *curpps = 0; rv = 1; - } else if (maxpps < 0) + } else if (maxpps < 0) { rv = 1; - else if (*curpps < maxpps) + } else if (*curpps < maxpps) { rv = 1; - else + } else { rv = 0; - if (*curpps + 1 > 0) + } + if (*curpps + 1 > 0) { *curpps = *curpps + 1; + } - return (rv); + return rv; } -/* - * Initialize lock group for audit related locks/mutexes. - */ -void -_audit_lck_grp_init(void) +int +audit_send_trigger(unsigned int trigger) { - audit_lck_grp = lck_grp_alloc_init("Audit", LCK_GRP_ATTR_NULL); + mach_port_t audit_port; + int error; - KASSERT(audit_lck_grp != NULL, - ("audit_get_lck_grp: Could not allocate the audit lock group.")); + error = host_get_audit_control_port(host_priv_self(), &audit_port); + if (error == KERN_SUCCESS && audit_port != MACH_PORT_NULL) { + (void)audit_triggers(audit_port, trigger); + ipc_port_release_send(audit_port); + return 0; + } else { + printf("Cannot get audit control port\n"); + return error; + } } int -audit_send_trigger(unsigned int trigger) +audit_send_analytics(char* signing_id, char* process_name) { mach_port_t audit_port; int error; error = host_get_audit_control_port(host_priv_self(), &audit_port); if (error == KERN_SUCCESS && audit_port != MACH_PORT_NULL) { - (void)audit_triggers(audit_port, trigger); + (void)audit_analytics(audit_port, signing_id, process_name); ipc_port_release_send(audit_port); - return (0); + return 0; } else { - printf("Cannot get audit control port\n"); - return (error); + printf("Cannot get audit control port for analytics \n"); + return error; } } + #endif /* CONFIG_AUDIT */