1/*- 2 * Copyright (c) 2008-2009, Apple Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#ifndef _SECURITY_AUDIT_AUDIT_BSD_H 31#define _SECURITY_AUDIT_AUDIT_BSD_H 32 33#include <sys/cdefs.h> 34#include <machine/endian.h> 35 36#if defined(_KERNEL) || defined(KERNEL) 37 38#if DIAGNOSTIC 39#ifdef KASSERT 40#undef KASSERT 41#endif 42#ifdef AUDIT_KASSERT_DEBUG 43#define KASSERT(exp, msg) do { \ 44 if (__builtin_expect(!(exp), 0)) { \ 45 printf("%s:%d KASSERT failed: ", __FILE__, __LINE__); \ 46 printf msg; \ 47 printf("\n"); \ 48 } \ 49} while (0) 50#else 51#define KASSERT(exp, msg) do { \ 52 if (__builtin_expect(!(exp), 0)) \ 53 panic msg; \ 54} while (0) 55#endif 56#endif /* DIAGNOSTIC */ 57 58#define AU_MAX_LCK_NAME 32 59 60#if __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN 61#define be16enc(p, d) *(p) = (d) 62#define be32enc(p, d) *(p) = (d) 63#define be64enc(p, d) *(p) = (d) 64 65#else /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ 66 67#include <libkern/OSByteOrder.h> 68 69#define be16enc(p, d) OSWriteSwapInt16(p, 0, d) 70#define be32enc(p, d) OSWriteSwapInt32(p, 0, d) 71#define be64enc(p, d) OSWriteSwapInt64(p, 0, d) 72#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ 73 74/* 75 * BSD kernel memory allocation. 76 */ 77#define AUDIT_MALLOC_DEBUG 0 /* Change to 1 for malloc debugging. */ 78 79#define M_AUDITUNKNOWN 0 80#define M_AUDITDATA 1 81#define M_AUDITPATH 2 82#define M_AUDITTEXT 3 83#define M_AUDITBSM 4 84#define M_AUDITEVCLASS 5 85#define M_AUDIT_PIPE 6 86#define M_AUDIT_PIPE_ENTRY 7 87#define M_AUDIT_PIPE_PRESELECT 8 88#define M_AU_SESSION 9 89#define M_AU_EV_PLIST 10 90 91#define NUM_MALLOC_TYPES 11 92 93#ifdef M_WAITOK 94#undef M_WAITOK 95#define M_WAITOK 0x0000 /* ok to block */ 96#endif 97#ifdef M_NOWAIT 98#undef M_NOWAIT 99#endif 100#define M_NOWAIT 0x0001 /* do not block */ 101#ifdef M_ZERO 102#undef M_ZERO 103#endif 104#define M_ZERO 0x0004 /* bzero the allocation */ 105 106#ifdef M_MAGIC 107#undef M_MAGIC 108#endif 109#define M_MAGIC 877983977 110 111#ifdef MALLOC_DEFINE 112#undef MALLOC_DEFINE 113#endif 114#if AUDIT_MALLOC_DEBUG 115struct au_malloc_type { 116 SInt64 mt_size; 117 SInt64 mt_maxsize; 118 SInt32 mt_inuse; 119 SInt32 mt_maxused; 120 unsigned mt_type; 121 unsigned mt_magic; 122 const char *mt_shortdesc; 123 const char *mt_lastcaller; 124}; 125typedef struct au_malloc_type au_malloc_type_t; 126 127#define MALLOC_DEFINE(type, shortdesc, longdesc) \ 128 au_malloc_type_t audit_##type[1] = { \ 129 { 0, 0, 0, 0, (type < NUM_MALLOC_TYPES) ? type :\ 130 M_AUDITUNKNOWN, M_MAGIC, shortdesc, NULL } \ 131 } 132 133extern au_malloc_type_t *audit_malloc_types[]; 134 135#else 136 137struct au_malloc_type { 138 uint32_t mt_magic; 139 const char *mt_shortdesc; 140}; 141typedef struct au_malloc_type au_malloc_type_t; 142 143#define MALLOC_DEFINE(type, shortdesc, longdesc) \ 144 au_malloc_type_t audit_##type[1] = { \ 145 {M_MAGIC, shortdesc } \ 146 } 147 148#endif /* AUDIT_MALLOC_DEBUG */ 149 150#ifdef MALLOC_DECLARE 151#undef MALLOC_DECLARE 152#endif 153#define MALLOC_DECLARE(type) \ 154 extern au_malloc_type_t audit_##type[] 155 156#if AUDIT_MALLOC_DEBUG 157#define malloc(sz, tp, fl) _audit_malloc(sz, audit_##tp, fl, __FUNCTION__) 158void *_audit_malloc(size_t size, au_malloc_type_t *type, int flags, 159 const char *fn); 160#else 161#define malloc(sz, tp, fl) _audit_malloc(sz, audit_##tp, fl) 162void *_audit_malloc(size_t size, au_malloc_type_t *type, int flags); 163#endif 164 165#define free(ad, tp) _audit_free(ad, audit_##tp) 166void _audit_free(void *addr, au_malloc_type_t *type); 167 168/* 169 * BSD condition variable. 170 */ 171struct cv { 172 const char *cv_description; 173 int cv_waiters; 174}; 175 176/* 177 * BSD mutex. 178 */ 179struct mtx { 180 lck_mtx_t *mtx_lock; 181#if DIAGNOSTIC 182 char mtx_name[AU_MAX_LCK_NAME]; 183#endif 184}; 185 186/* 187 * BSD rw lock. 188 */ 189struct rwlock { 190 lck_rw_t *rw_lock; 191#if DIAGNOSTIC 192 char rw_name[AU_MAX_LCK_NAME]; 193#endif 194}; 195 196/* 197 * Sleep lock. 198 */ 199struct slck { 200 lck_mtx_t *sl_mtx; 201 int sl_locked; 202 int sl_waiting; 203#if DIAGNOSTIC 204 char sl_name[AU_MAX_LCK_NAME]; 205#endif 206}; 207 208/* 209 * Recursive lock. 210 */ 211struct rlck { 212 lck_mtx_t *rl_mtx; 213 uint32_t rl_recurse; 214 thread_t rl_thread; 215#if DIAGNOSTIC 216 char rl_name[AU_MAX_LCK_NAME]; 217#endif 218}; 219 220/* 221 * BSD condition variables functions. 222 */ 223void _audit_cv_init(struct cv *cvp, const char *desc); 224void _audit_cv_destroy(struct cv *cvp); 225void _audit_cv_signal(struct cv *cvp); 226void _audit_cv_broadcast(struct cv *cvp); 227void _audit_cv_wait(struct cv *cvp, lck_mtx_t *mp, const char *desc); 228int _audit_cv_wait_sig(struct cv *cvp, lck_mtx_t *mp, const char *desc); 229int _audit_cv_wait_continuation(struct cv *cvp, lck_mtx_t *mp, 230 thread_continue_t function); 231#define cv_init(cvp, desc) _audit_cv_init(cvp, desc) 232#define cv_destroy(cvp) _audit_cv_destroy(cvp) 233#define cv_signal(cvp) _audit_cv_signal(cvp) 234#define cv_broadcast(cvp) _audit_cv_broadcast(cvp) 235#define cv_broadcastpri(cvp, pri) _audit_cv_broadcast(cvp) 236#define cv_wait(cvp, mp) _audit_cv_wait(cvp, (mp)->mtx_lock, #cvp) 237#define cv_wait_sig(cvp, mp) _audit_cv_wait_sig(cvp, (mp)->mtx_lock, #cvp) 238#define cv_wait_continuation(cvp,mp,f) \ 239 _audit_cv_wait_continuation(cvp, (mp)->mtx_lock, f) 240 241/* 242 * BSD Mutexes. 243 */ 244void _audit_mtx_init(struct mtx *mp, const char *name); 245void _audit_mtx_destroy(struct mtx *mp); 246#define mtx_init(mp, name, type, opts) \ 247 _audit_mtx_init(mp, name) 248#define mtx_lock(mp) lck_mtx_lock((mp)->mtx_lock) 249#define mtx_unlock(mp) lck_mtx_unlock((mp)->mtx_lock) 250#define mtx_destroy(mp) _audit_mtx_destroy(mp) 251#define mtx_yield(mp) lck_mtx_yield((mp)->mtx_lock) 252 253/* 254 * Sleep lock functions. 255 */ 256void _audit_slck_init(struct slck *lp, const char *grpname); 257wait_result_t _audit_slck_lock(struct slck *lp, int intr); 258void _audit_slck_unlock(struct slck *lp); 259int _audit_slck_trylock(struct slck *lp); 260void _audit_slck_assert(struct slck *lp, u_int assert); 261void _audit_slck_destroy(struct slck *lp); 262#define slck_init(lp, name) _audit_slck_init((lp), (name)) 263#define slck_lock(lp) _audit_slck_lock((lp), 0) 264#define slck_lock_sig(lp) (_audit_slck_lock((lp), 1) != THREAD_AWAKENED) 265#define slck_unlock(lp) _audit_slck_unlock((lp)) 266#define slck_destroy(lp) _audit_slck_destroy((lp)) 267 268/* 269 * Recursive lock functions. 270 */ 271void _audit_rlck_init(struct rlck *lp, const char *grpname); 272void _audit_rlck_lock(struct rlck *lp); 273void _audit_rlck_unlock(struct rlck *lp); 274void _audit_rlck_assert(struct rlck *lp, u_int assert); 275void _audit_rlck_destroy(struct rlck *lp); 276#define rlck_init(lp, name) _audit_rlck_init((lp), (name)) 277#define rlck_lock(lp) _audit_rlck_lock((lp)) 278#define rlck_unlock(lp) _audit_rlck_unlock((lp)) 279#define rlck_destroy(lp) _audit_rlck_destroy((lp)) 280 281/* 282 * BSD rw locks. 283 */ 284void _audit_rw_init(struct rwlock *lp, const char *name); 285void _audit_rw_destroy(struct rwlock *lp); 286#define rw_init(lp, name) _audit_rw_init(lp, name) 287#define rw_rlock(lp) lck_rw_lock_shared((lp)->rw_lock) 288#define rw_runlock(lp) lck_rw_unlock_shared((lp)->rw_lock) 289#define rw_wlock(lp) lck_rw_lock_exclusive((lp)->rw_lock) 290#define rw_wunlock(lp) lck_rw_unlock_exclusive((lp)->rw_lock) 291#define rw_destroy(lp) _audit_rw_destroy(lp) 292 293#define MA_OWNED LCK_MTX_ASSERT_OWNED 294#define RA_LOCKED LCK_RW_ASSERT_HELD 295#define RA_RLOCKED LCK_RW_ASSERT_SHARED 296#define RA_WLOCKED LCK_RW_ASSERT_EXCLUSIVE 297#define SA_LOCKED LCK_RW_ASSERT_HELD 298#define SA_XLOCKED LCK_RW_ASSERT_EXCLUSIVE 299#define SL_OWNED LCK_MTX_ASSERT_OWNED 300#define SL_NOTOWNED LCK_MTX_ASSERT_NOTOWNED 301#if DIAGNOSTIC 302#define mtx_assert(mp, wht) lck_mtx_assert((mp)->mtx_lock, wht) 303#define rw_assert(lp, wht) lck_rw_assert((lp)->rw_lock, wht) 304#define sx_assert(lp, wht) lck_rw_assert((lp)->sx_lock, wht) 305#define rlck_assert(lp, wht) _audit_rlck_assert((lp), wht) 306#define slck_assert(lp, wht) _audit_slck_assert((lp), wht) 307#else 308#define mtx_assert(mp, wht) 309#define rw_assert(lp, wht) 310#define sx_assert(lp, wht) 311#define rlck_assert(lp, wht) 312#define slck_assert(lp, wht) 313#endif /* DIAGNOSTIC */ 314 315/* 316 * Synchronization initialization. 317 */ 318void _audit_lck_grp_init(void); 319 320/* 321 * BSD (IPv6) event rate limiter. 322 */ 323int _audit_ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps); 324#define ppsratecheck(tv, cr, mr) _audit_ppsratecheck(tv, cr, mr) 325 326#endif /* defined(_KERNEL) || defined(KERNEL) */ 327#endif /* _SECURITY_AUDIT_AUDIT_BSD_H */ 328