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
116struct 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};
126typedef 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
134extern au_malloc_type_t *audit_malloc_types[];
135
136#else
137
138struct au_malloc_type {
139 uint32_t mt_magic;
140 const char *mt_shortdesc;
141};
142typedef 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 */
160struct cv {
161 const char *cv_description;
162 int cv_waiters;
163};
164
165/*
166 * BSD mutex.
167 */
168struct 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 */
178struct 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 */
188struct 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 */
200struct 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 */
212void _audit_cv_init(struct cv *cvp, const char *desc);
213void _audit_cv_destroy(struct cv *cvp);
214void _audit_cv_signal(struct cv *cvp);
215void _audit_cv_broadcast(struct cv *cvp);
216void _audit_cv_wait(struct cv *cvp, lck_mtx_t *mp, const char *desc);
217int _audit_cv_wait_sig(struct cv *cvp, lck_mtx_t *mp, const char *desc);
218int _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 */
233void _audit_mtx_init(struct mtx *mp, const char *name);
234void _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 */
245void _audit_slck_init(struct slck *lp, const char *grpname);
246wait_result_t _audit_slck_lock(struct slck *lp, int intr);
247void _audit_slck_unlock(struct slck *lp);
248int _audit_slck_trylock(struct slck *lp);
249void _audit_slck_assert(struct slck *lp, u_int assert);
250void _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 */
260void _audit_rlck_init(struct rlck *lp, const char *grpname);
261void _audit_rlck_lock(struct rlck *lp);
262void _audit_rlck_unlock(struct rlck *lp);
263void _audit_rlck_assert(struct rlck *lp, u_int assert);
264void _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 */
273void _audit_rw_init(struct rwlock *lp, const char *name);
274void _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 */
307int _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