#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
#define AU_MAX_LCK_NAME 32
#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
#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
#define AUDIT_MALLOC_DEBUG 0
#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_WAITOK
#undef M_WAITOK
#define M_WAITOK 0x0000
#endif
#ifdef M_NOWAIT
#undef M_NOWAIT
#endif
#define M_NOWAIT 0x0001
#ifdef M_ZERO
#undef M_ZERO
#endif
#define M_ZERO 0x0004
#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
#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);
struct cv {
const char *cv_description;
int cv_waiters;
};
struct mtx {
lck_mtx_t *mtx_lock;
#if DIAGNOSTIC
char mtx_name[AU_MAX_LCK_NAME];
#endif
};
struct rwlock {
lck_rw_t *rw_lock;
#if DIAGNOSTIC
char rw_name[AU_MAX_LCK_NAME];
#endif
};
struct slck {
lck_mtx_t *sl_mtx;
int sl_locked;
int sl_waiting;
#if DIAGNOSTIC
char sl_name[AU_MAX_LCK_NAME];
#endif
};
struct rlck {
lck_mtx_t *rl_mtx;
uint32_t rl_recurse;
thread_t rl_thread;
#if DIAGNOSTIC
char rl_name[AU_MAX_LCK_NAME];
#endif
};
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);
int _audit_cv_wait_continuation(struct cv *cvp, lck_mtx_t *mp,
thread_continue_t function);
#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)
#define cv_wait_continuation(cvp,mp,f) \
_audit_cv_wait_continuation(cvp, (mp)->mtx_lock, f)
void _audit_mtx_init(struct mtx *mp, const char *name);
void _audit_mtx_destroy(struct mtx *mp);
#define mtx_init(mp, name, type, opts) \
_audit_mtx_init(mp, name)
#define mtx_lock(mp) lck_mtx_lock((mp)->mtx_lock)
#define mtx_unlock(mp) lck_mtx_unlock((mp)->mtx_lock)
#define mtx_destroy(mp) _audit_mtx_destroy(mp)
#define mtx_yield(mp) lck_mtx_yield((mp)->mtx_lock)
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))
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))
void _audit_rw_init(struct rwlock *lp, const char *name);
void _audit_rw_destroy(struct rwlock *lp);
#define rw_init(lp, name) _audit_rw_init(lp, name)
#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) _audit_rw_destroy(lp)
#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
void _audit_lck_grp_init(void);
int _audit_ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps);
#define ppsratecheck(tv, cr, mr) _audit_ppsratecheck(tv, cr, mr)
#endif
#endif