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 #include <kern/kalloc.h> 38 39 #if DIAGNOSTIC 40 #ifdef KASSERT 41 #undef KASSERT 42 #endif 43 #ifdef AUDIT_KASSERT_DEBUG 44 #define KASSERT(exp, msg) do { \ 45 if (__builtin_expect(!(exp), 0)) { \ 46 printf("%s:%d KASSERT failed: ", __FILE__, __LINE__); \ 47 printf msg; \ 48 printf("\n"); \ 49 } \ 50 } while (0) 51 #else 52 #define KASSERT(exp, msg) do { \ 53 if (__builtin_expect(!(exp), 0)) \ 54 panic msg; \ 55 } while (0) 56 #endif 57 #endif /* DIAGNOSTIC */ 58 59 #define AU_MAX_LCK_NAME 32 60 61 #if __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN 62 #define be16enc(p, d) *(p) = (d) 63 #define be32enc(p, d) *(p) = (d) 64 #define be64enc(p, d) *(p) = (d) 65 66 #else /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ 67 68 #include <libkern/OSByteOrder.h> 69 70 #define be16enc(p, d) OSWriteSwapInt16(p, 0, d) 71 #define be32enc(p, d) OSWriteSwapInt32(p, 0, d) 72 #define be64enc(p, d) OSWriteSwapInt64(p, 0, d) 73 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */ 74 75 /* 76 * BSD kernel memory allocation. 77 */ 78 #define AUDIT_MALLOC_DEBUG 0 /* Change to 1 for malloc debugging. */ 79 80 #define M_AUDITUNKNOWN 0 81 #define M_AUDITDATA 1 82 #define M_AUDITPATH 2 83 #define M_AUDITTEXT 3 84 #define M_AUDITBSM 4 85 #define M_AUDITEVCLASS 5 86 #define M_AUDIT_PIPE 6 87 #define M_AUDIT_PIPE_ENTRY 7 88 #define M_AUDIT_PIPE_PRESELECT 8 89 #define M_AU_SESSION 9 90 #define M_AU_EV_PLIST 10 91 92 #define NUM_MALLOC_TYPES 11 93 94 #ifdef M_WAITOK 95 #undef M_WAITOK 96 #define M_WAITOK 0x0000 /* ok to block */ 97 #endif 98 #ifdef M_NOWAIT 99 #undef M_NOWAIT 100 #endif 101 #define M_NOWAIT 0x0001 /* do not block */ 102 #ifdef M_ZERO 103 #undef M_ZERO 104 #endif 105 #define M_ZERO 0x0004 /* bzero the allocation */ 106 107 #ifdef M_MAGIC 108 #undef M_MAGIC 109 #endif 110 #define M_MAGIC 877983977 111 112 #ifdef MALLOC_DEFINE 113 #undef MALLOC_DEFINE 114 #endif 115 #if AUDIT_MALLOC_DEBUG 116 struct au_malloc_type { 117 SInt64 mt_size; 118 SInt64 mt_maxsize; 119 SInt32 mt_inuse; 120 SInt32 mt_maxused; 121 unsigned mt_type; 122 unsigned mt_magic; 123 const char *mt_shortdesc; 124 const char *mt_lastcaller; 125 }; 126 typedef struct au_malloc_type au_malloc_type_t; 127 128 #define MALLOC_DEFINE(type, shortdesc, longdesc) \ 129 au_malloc_type_t audit_##type[1] = { \ 130 { 0, 0, 0, 0, (type < NUM_MALLOC_TYPES) ? type :\ 131 M_AUDITUNKNOWN, M_MAGIC, shortdesc, NULL } \ 132 } 133 134 extern au_malloc_type_t *audit_malloc_types[]; 135 136 #else 137 138 struct au_malloc_type { 139 uint32_t mt_magic; 140 const char *mt_shortdesc; 141 }; 142 typedef struct au_malloc_type au_malloc_type_t; 143 144 #define MALLOC_DEFINE(type, shortdesc, longdesc) \ 145 __unused au_malloc_type_t audit_##type[1] = { \ 146 {M_MAGIC, shortdesc } \ 147 } 148 149 #endif /* AUDIT_MALLOC_DEBUG */ 150 151 #ifdef MALLOC_DECLARE 152 #undef MALLOC_DECLARE 153 #endif 154 #define MALLOC_DECLARE(type) \ 155 extern au_malloc_type_t audit_##type[] 156 157 /* 158 * BSD condition variable. 159 */ 160 struct cv { 161 const char *cv_description; 162 int cv_waiters; 163 }; 164 165 /* 166 * BSD mutex. 167 */ 168 struct mtx { 169 lck_mtx_t *mtx_lock; 170 #if DIAGNOSTIC 171 char mtx_name[AU_MAX_LCK_NAME]; 172 #endif 173 }; 174 175 /* 176 * BSD rw lock. 177 */ 178 struct rwlock { 179 lck_rw_t *rw_lock; 180 #if DIAGNOSTIC 181 char rw_name[AU_MAX_LCK_NAME]; 182 #endif 183 }; 184 185 /* 186 * Sleep lock. 187 */ 188 struct slck { 189 lck_mtx_t *sl_mtx; 190 int sl_locked; 191 int sl_waiting; 192 #if DIAGNOSTIC 193 char sl_name[AU_MAX_LCK_NAME]; 194 #endif 195 }; 196 197 /* 198 * Recursive lock. 199 */ 200 struct rlck { 201 lck_mtx_t *rl_mtx; 202 uint32_t rl_recurse; 203 thread_t rl_thread; 204 #if DIAGNOSTIC 205 char rl_name[AU_MAX_LCK_NAME]; 206 #endif 207 }; 208 209 /* 210 * BSD condition variables functions. 211 */ 212 void _audit_cv_init(struct cv *cvp, const char *desc); 213 void _audit_cv_destroy(struct cv *cvp); 214 void _audit_cv_signal(struct cv *cvp); 215 void _audit_cv_broadcast(struct cv *cvp); 216 void _audit_cv_wait(struct cv *cvp, lck_mtx_t *mp, const char *desc); 217 int _audit_cv_wait_sig(struct cv *cvp, lck_mtx_t *mp, const char *desc); 218 int _audit_cv_wait_continuation(struct cv *cvp, lck_mtx_t *mp, 219 thread_continue_t function); 220 #define cv_init(cvp, desc) _audit_cv_init(cvp, desc) 221 #define cv_destroy(cvp) _audit_cv_destroy(cvp) 222 #define cv_signal(cvp) _audit_cv_signal(cvp) 223 #define cv_broadcast(cvp) _audit_cv_broadcast(cvp) 224 #define cv_broadcastpri(cvp, pri) _audit_cv_broadcast(cvp) 225 #define cv_wait(cvp, mp) _audit_cv_wait(cvp, (mp)->mtx_lock, #cvp) 226 #define cv_wait_sig(cvp, mp) _audit_cv_wait_sig(cvp, (mp)->mtx_lock, #cvp) 227 #define cv_wait_continuation(cvp, mp, f) \ 228 _audit_cv_wait_continuation(cvp, (mp)->mtx_lock, f) 229 230 /* 231 * BSD Mutexes. 232 */ 233 void _audit_mtx_init(struct mtx *mp, const char *name); 234 void _audit_mtx_destroy(struct mtx *mp); 235 #define mtx_init(mp, name, type, opts) \ 236 _audit_mtx_init(mp, name) 237 #define mtx_lock(mp) lck_mtx_lock((mp)->mtx_lock) 238 #define mtx_unlock(mp) lck_mtx_unlock((mp)->mtx_lock) 239 #define mtx_destroy(mp) _audit_mtx_destroy(mp) 240 #define mtx_yield(mp) lck_mtx_yield((mp)->mtx_lock) 241 242 /* 243 * Sleep lock functions. 244 */ 245 void _audit_slck_init(struct slck *lp, const char *grpname); 246 wait_result_t _audit_slck_lock(struct slck *lp, int intr); 247 void _audit_slck_unlock(struct slck *lp); 248 int _audit_slck_trylock(struct slck *lp); 249 void _audit_slck_assert(struct slck *lp, u_int assert); 250 void _audit_slck_destroy(struct slck *lp); 251 #define slck_init(lp, name) _audit_slck_init((lp), (name)) 252 #define slck_lock(lp) _audit_slck_lock((lp), 0) 253 #define slck_lock_sig(lp) (_audit_slck_lock((lp), 1) != THREAD_AWAKENED) 254 #define slck_unlock(lp) _audit_slck_unlock((lp)) 255 #define slck_destroy(lp) _audit_slck_destroy((lp)) 256 257 /* 258 * Recursive lock functions. 259 */ 260 void _audit_rlck_init(struct rlck *lp, const char *grpname); 261 void _audit_rlck_lock(struct rlck *lp); 262 void _audit_rlck_unlock(struct rlck *lp); 263 void _audit_rlck_assert(struct rlck *lp, u_int assert); 264 void _audit_rlck_destroy(struct rlck *lp); 265 #define rlck_init(lp, name) _audit_rlck_init((lp), (name)) 266 #define rlck_lock(lp) _audit_rlck_lock((lp)) 267 #define rlck_unlock(lp) _audit_rlck_unlock((lp)) 268 #define rlck_destroy(lp) _audit_rlck_destroy((lp)) 269 270 /* 271 * BSD rw locks. 272 */ 273 void _audit_rw_init(struct rwlock *lp, const char *name); 274 void _audit_rw_destroy(struct rwlock *lp); 275 #define rw_init(lp, name) _audit_rw_init(lp, name) 276 #define rw_rlock(lp) lck_rw_lock_shared((lp)->rw_lock) 277 #define rw_runlock(lp) lck_rw_unlock_shared((lp)->rw_lock) 278 #define rw_wlock(lp) lck_rw_lock_exclusive((lp)->rw_lock) 279 #define rw_wunlock(lp) lck_rw_unlock_exclusive((lp)->rw_lock) 280 #define rw_destroy(lp) _audit_rw_destroy(lp) 281 282 #define MA_OWNED LCK_MTX_ASSERT_OWNED 283 #define RA_LOCKED LCK_RW_ASSERT_HELD 284 #define RA_RLOCKED LCK_RW_ASSERT_SHARED 285 #define RA_WLOCKED LCK_RW_ASSERT_EXCLUSIVE 286 #define SA_LOCKED LCK_RW_ASSERT_HELD 287 #define SA_XLOCKED LCK_RW_ASSERT_EXCLUSIVE 288 #define SL_OWNED LCK_MTX_ASSERT_OWNED 289 #define SL_NOTOWNED LCK_MTX_ASSERT_NOTOWNED 290 #if DIAGNOSTIC 291 #define mtx_assert(mp, wht) lck_mtx_assert((mp)->mtx_lock, wht) 292 #define rw_assert(lp, wht) lck_rw_assert((lp)->rw_lock, wht) 293 #define sx_assert(lp, wht) lck_rw_assert((lp)->sx_lock, wht) 294 #define rlck_assert(lp, wht) _audit_rlck_assert((lp), wht) 295 #define slck_assert(lp, wht) _audit_slck_assert((lp), wht) 296 #else 297 #define mtx_assert(mp, wht) 298 #define rw_assert(lp, wht) 299 #define sx_assert(lp, wht) 300 #define rlck_assert(lp, wht) 301 #define slck_assert(lp, wht) 302 #endif /* DIAGNOSTIC */ 303 304 /* 305 * BSD (IPv6) event rate limiter. 306 */ 307 int _audit_ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps); 308 #define ppsratecheck(tv, cr, mr) _audit_ppsratecheck(tv, cr, mr) 309 310 #endif /* defined(_KERNEL) || defined(KERNEL) */ 311 #endif /* _SECURITY_AUDIT_AUDIT_BSD_H */ 312