--- /dev/null
+/*-
+ * 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 <sys/cdefs.h>
+#include <machine/endian.h>
+
+#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 <libkern/OSByteOrder.h>
+
+#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 */