/*- * Copyright (c) 2008-2009, Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _SECURITY_AUDIT_AUDIT_BSD_H #define _SECURITY_AUDIT_AUDIT_BSD_H #include #include #if defined(_KERNEL) || defined(KERNEL) #if DIAGNOSTIC #ifdef KASSERT #undef KASSERT #endif #ifdef AUDIT_KASSERT_DEBUG #define KASSERT(exp, msg) do { \ if (__builtin_expect(!(exp), 0)) { \ printf("%s:%d KASSERT failed: ", __FILE__, __LINE__); \ printf msg; \ printf("\n"); \ } \ } while (0) #else #define KASSERT(exp, msg) do { \ if (__builtin_expect(!(exp), 0)) \ panic msg; \ } while (0) #endif #endif /* DIAGNOSTIC */ #define AU_MAX_LCK_NAME 32 #if __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN #define be16enc(p, d) *(p) = (d) #define be32enc(p, d) *(p) = (d) #define be64enc(p, d) *(p) = (d) #else /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ #include #define be16enc(p, d) OSWriteSwapInt16(p, 0, d) #define be32enc(p, d) OSWriteSwapInt32(p, 0, d) #define be64enc(p, d) OSWriteSwapInt64(p, 0, d) #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ /* * BSD kernel memory allocation. */ #define AUDIT_MALLOC_DEBUG 0 /* Change to 1 for malloc debugging. */ #define M_AUDITUNKNOWN 0 #define M_AUDITDATA 1 #define M_AUDITPATH 2 #define M_AUDITTEXT 3 #define M_AUDITBSM 4 #define M_AUDITEVCLASS 5 #define M_AUDIT_PIPE 6 #define M_AUDIT_PIPE_ENTRY 7 #define M_AUDIT_PIPE_PRESELECT 8 #define M_AU_SESSION 9 #define M_AU_EV_PLIST 10 #define NUM_MALLOC_TYPES 11 #ifdef M_NOWAIT #undef M_NOWAIT #endif #define M_NOWAIT 0x0000 /* do not block */ #ifdef M_WAITOK #undef M_WAITOK #define M_WAITOK 0x0001 /* ok to block */ #endif #ifdef M_ZERO #undef M_ZERO #endif #define M_ZERO 0x0004 /* bzero the allocation */ #ifdef M_MAGIC #undef M_MAGIC #endif #define M_MAGIC 877983977 #ifdef MALLOC_DEFINE #undef MALLOC_DEFINE #endif #if AUDIT_MALLOC_DEBUG struct au_malloc_type { SInt64 mt_size; SInt64 mt_maxsize; SInt32 mt_inuse; SInt32 mt_maxused; unsigned mt_type; unsigned mt_magic; const char *mt_shortdesc; const char *mt_lastcaller; }; typedef struct au_malloc_type au_malloc_type_t; #define MALLOC_DEFINE(type, shortdesc, longdesc) \ au_malloc_type_t audit_##type[1] = { \ { 0, 0, 0, 0, (type < NUM_MALLOC_TYPES) ? type :\ M_AUDITUNKNOWN, M_MAGIC, shortdesc, NULL } \ } extern au_malloc_type_t *audit_malloc_types[]; #else struct au_malloc_type { uint32_t mt_magic; const char *mt_shortdesc; }; typedef struct au_malloc_type au_malloc_type_t; #define MALLOC_DEFINE(type, shortdesc, longdesc) \ au_malloc_type_t audit_##type[1] = { \ {M_MAGIC, shortdesc } \ } #endif /* AUDIT_MALLOC_DEBUG */ #ifdef MALLOC_DECLARE #undef MALLOC_DECLARE #endif #define MALLOC_DECLARE(type) \ extern au_malloc_type_t audit_##type[] #if AUDIT_MALLOC_DEBUG #define malloc(sz, tp, fl) _audit_malloc(sz, audit_##tp, fl, __FUNCTION__) void *_audit_malloc(size_t size, au_malloc_type_t *type, int flags, const char *fn); #else #define malloc(sz, tp, fl) _audit_malloc(sz, audit_##tp, fl) void *_audit_malloc(size_t size, au_malloc_type_t *type, int flags); #endif #define free(ad, tp) _audit_free(ad, audit_##tp) void _audit_free(void *addr, au_malloc_type_t *type); /* * BSD condition variable. */ struct cv { const char *cv_description; int cv_waiters; }; /* * BSD mutex. */ struct mtx { lck_mtx_t *mtx_lock; #if DIAGNOSTIC char mtx_name[AU_MAX_LCK_NAME]; #endif }; /* * BSD rw lock. */ struct rwlock { lck_rw_t *rw_lock; #if DIAGNOSTIC char rw_name[AU_MAX_LCK_NAME]; #endif }; /* * Sleep lock. */ struct slck { lck_mtx_t *sl_mtx; int sl_locked; int sl_waiting; #if DIAGNOSTIC char sl_name[AU_MAX_LCK_NAME]; #endif }; /* * Recursive lock. */ struct rlck { lck_mtx_t *rl_mtx; uint32_t rl_recurse; thread_t rl_thread; #if DIAGNOSTIC char rl_name[AU_MAX_LCK_NAME]; #endif }; /* * BSD condition variables functions. */ void _audit_cv_init(struct cv *cvp, const char *desc); void _audit_cv_destroy(struct cv *cvp); void _audit_cv_signal(struct cv *cvp); void _audit_cv_broadcast(struct cv *cvp); void _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); int _audit_cv_wait_continuation(struct cv *cvp, lck_mtx_t *mp, thread_continue_t function); #define cv_init(cvp, desc) _audit_cv_init(cvp, desc) #define cv_destroy(cvp) _audit_cv_destroy(cvp) #define cv_signal(cvp) _audit_cv_signal(cvp) #define cv_broadcast(cvp) _audit_cv_broadcast(cvp) #define cv_broadcastpri(cvp, pri) _audit_cv_broadcast(cvp) #define cv_wait(cvp, mp) _audit_cv_wait(cvp, (mp)->mtx_lock, #cvp) #define cv_wait_sig(cvp, mp) _audit_cv_wait_sig(cvp, (mp)->mtx_lock, #cvp) #define cv_wait_continuation(cvp,mp,f) \ _audit_cv_wait_continuation(cvp, (mp)->mtx_lock, f) /* * BSD Mutexes. */ void _audit_mtx_init(struct mtx *mp, const char *name); void _audit_mtx_destroy(struct mtx *mp); #define mtx_init(mp, name, type, opts) \ _audit_mtx_init(mp, name) #define mtx_lock(mp) lck_mtx_lock((mp)->mtx_lock) #define mtx_unlock(mp) lck_mtx_unlock((mp)->mtx_lock) #define mtx_destroy(mp) _audit_mtx_destroy(mp) #define mtx_yield(mp) lck_mtx_yield((mp)->mtx_lock) /* * Sleep lock functions. */ void _audit_slck_init(struct slck *lp, const char *grpname); wait_result_t _audit_slck_lock(struct slck *lp, int intr); void _audit_slck_unlock(struct slck *lp); int _audit_slck_trylock(struct slck *lp); void _audit_slck_assert(struct slck *lp, u_int assert); void _audit_slck_destroy(struct slck *lp); #define slck_init(lp, name) _audit_slck_init((lp), (name)) #define slck_lock(lp) _audit_slck_lock((lp), 0) #define slck_lock_sig(lp) (_audit_slck_lock((lp), 1) != THREAD_AWAKENED) #define slck_unlock(lp) _audit_slck_unlock((lp)) #define slck_destroy(lp) _audit_slck_destroy((lp)) /* * Recursive lock functions. */ void _audit_rlck_init(struct rlck *lp, const char *grpname); void _audit_rlck_lock(struct rlck *lp); void _audit_rlck_unlock(struct rlck *lp); void _audit_rlck_assert(struct rlck *lp, u_int assert); void _audit_rlck_destroy(struct rlck *lp); #define rlck_init(lp, name) _audit_rlck_init((lp), (name)) #define rlck_lock(lp) _audit_rlck_lock((lp)) #define rlck_unlock(lp) _audit_rlck_unlock((lp)) #define rlck_destroy(lp) _audit_rlck_destroy((lp)) /* * BSD rw locks. */ void _audit_rw_init(struct rwlock *lp, const char *name); void _audit_rw_destroy(struct rwlock *lp); #define rw_init(lp, name) _audit_rw_init(lp, name) #define rw_rlock(lp) lck_rw_lock_shared((lp)->rw_lock) #define rw_runlock(lp) lck_rw_unlock_shared((lp)->rw_lock) #define rw_wlock(lp) lck_rw_lock_exclusive((lp)->rw_lock) #define rw_wunlock(lp) lck_rw_unlock_exclusive((lp)->rw_lock) #define rw_destroy(lp) _audit_rw_destroy(lp) #define MA_OWNED LCK_MTX_ASSERT_OWNED #define RA_LOCKED LCK_RW_ASSERT_HELD #define RA_RLOCKED LCK_RW_ASSERT_SHARED #define RA_WLOCKED LCK_RW_ASSERT_EXCLUSIVE #define SA_LOCKED LCK_RW_ASSERT_HELD #define SA_XLOCKED LCK_RW_ASSERT_EXCLUSIVE #define SL_OWNED LCK_MTX_ASSERT_OWNED #define SL_NOTOWNED LCK_MTX_ASSERT_NOTOWNED #if DIAGNOSTIC #define mtx_assert(mp, wht) lck_mtx_assert((mp)->mtx_lock, wht) #define rw_assert(lp, wht) lck_rw_assert((lp)->rw_lock, wht) #define sx_assert(lp, wht) lck_rw_assert((lp)->sx_lock, wht) #define rlck_assert(lp, wht) _audit_rlck_assert((lp), wht) #define slck_assert(lp, wht) _audit_slck_assert((lp), wht) #else #define mtx_assert(mp, wht) #define rw_assert(lp, wht) #define sx_assert(lp, wht) #define rlck_assert(lp, wht) #define slck_assert(lp, wht) #endif /* DIAGNOSTIC */ /* * Synchronization initialization. */ void _audit_lck_grp_init(void); /* * BSD (IPv6) event rate limiter. */ int _audit_ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps); #define ppsratecheck(tv, cr, mr) _audit_ppsratecheck(tv, cr, mr) #endif /* defined(_KERNEL) || defined(KERNEL) */ #endif /* _SECURITY_AUDIT_AUDIT_BSD_H */