X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3903760236c30e3b5ace7a4eefac3a269d68957c..eb6b6ca394357805f2bdba989abae309f718b4d8:/bsd/security/audit/audit_bsd.c diff --git a/bsd/security/audit/audit_bsd.c b/bsd/security/audit/audit_bsd.c index a08ab453d..5cfc16778 100644 --- a/bsd/security/audit/audit_bsd.c +++ b/bsd/security/audit/audit_bsd.c @@ -51,39 +51,41 @@ #include #include +#include + 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; -#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); @@ -92,11 +94,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, @@ -114,35 +116,39 @@ 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); + 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); + if (amdi_ptr == NULL) { + return ENOMEM; + } bzero(amdi_ptr, AU_MALLOC_DBINFO_SZ); /* - * 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; @@ -155,7 +161,7 @@ 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++; } @@ -164,13 +170,13 @@ audit_sysctl_malloc_debug(__unused struct sysctl_oid *oidp, __unused void *arg1, err = SYSCTL_OUT(req, amdi_ptr, sz); kfree(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. */ @@ -178,28 +184,35 @@ 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 = sizeof (*hdr) + size; + struct mhdr *hdr; + size_t memsize; + if (os_add_overflow(sizeof(*hdr), size, &memsize)) { + return NULL; + } - if (size == 0) - return (NULL); + if (size == 0) { + return NULL; + } if (flags & M_NOWAIT) { hdr = (void *)kalloc_noblock(memsize); } else { hdr = (void *)kalloc(memsize); - if (hdr == NULL) + if (hdr == NULL) { panic("_audit_malloc: kernel memory exhausted"); + } + } + 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) + 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); @@ -210,7 +223,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; } /* @@ -224,13 +237,15 @@ _audit_free(void *addr, __unused au_malloc_type_t *type) #endif { struct mhdr *hdr; - - if (addr == NULL) + + if (addr == NULL) { return; + } hdr = addr; hdr--; - KASSERT(hdr->mh_magic == AUDIT_MHMAGIC, - ("_audit_free(): hdr->mh_magic != AUDIT_MHMAGIC")); + if (hdr->mh_magic != AUDIT_MHMAGIC) { + panic("_audit_free(): hdr->mh_magic (%lx) != AUDIT_MHMAGIC", hdr->mh_magic); + } #if AUDIT_MALLOC_DEBUG if (type != NULL) { @@ -247,11 +262,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; } @@ -261,7 +276,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; } @@ -272,7 +286,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--; @@ -285,7 +298,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; @@ -300,7 +312,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); } @@ -314,9 +325,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); } /* @@ -330,17 +340,16 @@ _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, + 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); mp->mtx_lock = NULL; @@ -358,17 +367,16 @@ _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, + 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); lp->rw_lock = NULL; @@ -397,7 +405,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 @@ -406,12 +414,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, + 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; @@ -419,11 +426,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, @@ -441,7 +447,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. */ @@ -450,11 +456,10 @@ _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); lp->rl_mtx = NULL; @@ -468,13 +473,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); + } } /* @@ -487,12 +494,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, + 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; @@ -500,7 +506,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) @@ -511,13 +517,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; } /* @@ -526,7 +533,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) { @@ -539,7 +545,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) @@ -548,11 +554,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; } /* @@ -561,17 +568,17 @@ _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); lp->sl_mtx = NULL; @@ -584,14 +591,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 /* @@ -620,16 +627,18 @@ _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; } /* @@ -654,10 +663,10 @@ audit_send_trigger(unsigned int trigger) if (error == KERN_SUCCESS && audit_port != MACH_PORT_NULL) { (void)audit_triggers(audit_port, trigger); ipc_port_release_send(audit_port); - return (0); + return 0; } else { printf("Cannot get audit control port\n"); - return (error); + return error; } } #endif /* CONFIG_AUDIT */