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