X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/e2fac8b15b12a7979f72090454d850e612fc5b13..b0d623f7f2ae71ed96e60569f61f9a9a27016e80:/bsd/security/audit/audit_bsd.h diff --git a/bsd/security/audit/audit_bsd.h b/bsd/security/audit/audit_bsd.h new file mode 100644 index 000000000..23b61a5df --- /dev/null +++ b/bsd/security/audit/audit_bsd.h @@ -0,0 +1,329 @@ +/*- + * Copyright (c) 2008, 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 */ + +#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; + lck_grp_t *mtx_grp; +}; + +/* + * BSD rw lock. + */ +struct rwlock { + lck_rw_t *rw_lock; + lck_grp_t *rw_grp; +}; + +/* + * Sleep lock. + */ +struct slck { + lck_mtx_t *sl_mtx; + lck_grp_t *sl_grp; + int sl_locked; + int sl_waiting; +}; + +/* + * Recursive lock. + */ +struct rlck { + lck_mtx_t *rl_mtx; + lck_grp_t *rl_grp; + uint32_t rl_recurse; + thread_t rl_thread; +}; + +/* + * 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); +#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) + +/* + * BSD Mutexes. + */ +#define LOCK_MAX_NAME 64 +#define mtx_init(mp, name, type, opts) do { \ + (mp)->mtx_grp = lck_grp_alloc_init(name, LCK_GRP_ATTR_NULL); \ + (mp)->mtx_lock = lck_mtx_alloc_init((mp)->mtx_grp, \ + LCK_ATTR_NULL); \ +} while(0) +#define mtx_lock(mp) lck_mtx_lock((mp)->mtx_lock) +#define mtx_unlock(mp) lck_mtx_unlock((mp)->mtx_lock) +#define mtx_destroy(mp) do { \ + if ((mp)->mtx_lock) { \ + lck_mtx_free((mp)->mtx_lock, (mp)->mtx_grp); \ + (mp)->mtx_lock = 0; \ + } \ + if ((mp)->mtx_grp) { \ + lck_grp_free((mp)->mtx_grp); \ + (mp)->mtx_grp = 0; \ + } \ +} while (0) + +/* + * 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. + */ +#define rw_init(lp, name) do { \ + (lp)->rw_grp = lck_grp_alloc_init(name, LCK_GRP_ATTR_NULL); \ + (lp)->rw_lock = lck_rw_alloc_init((lp)->rw_grp, \ + LCK_ATTR_NULL); \ +} while(0) +#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) do { \ + if ((lp)->rw_lock) { \ + lck_rw_free((lp)->rw_lock, (lp)->rw_grp); \ + (lp)->rw_lock = 0; \ + } \ + if ((lp)->rw_grp) { \ + lck_grp_free((lp)->rw_grp); \ + (lp)->rw_grp = 0; \ + } \ +} while (0) + +#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 */ + +/* + * 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 */