From owner-trustedbsd-cvs@FreeBSD.ORG Mon Dec 4 18:38:36 2006 Return-Path: X-Original-To: trustedbsd-cvs@freebsd.org Delivered-To: trustedbsd-cvs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A0B4116A500 for ; Mon, 4 Dec 2006 18:38:36 +0000 (UTC) (envelope-from owner-perforce@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id F15BF43CB7 for ; Mon, 4 Dec 2006 18:38:00 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: from mx2.freebsd.org (mx2.freebsd.org [69.147.83.53]) by cyrus.watson.org (Postfix) with ESMTP id 092B146F53 for ; Mon, 4 Dec 2006 13:38:34 -0500 (EST) Received: from hub.freebsd.org (hub.freebsd.org [69.147.83.54]) by mx2.freebsd.org (Postfix) with ESMTP id 4EC5E5C8A5; Mon, 4 Dec 2006 18:38:26 +0000 (GMT) (envelope-from owner-perforce@freebsd.org) Received: by hub.freebsd.org (Postfix, from userid 32767) id C318416A47B; Mon, 4 Dec 2006 18:38:31 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 94C8A16A407 for ; Mon, 4 Dec 2006 18:38:31 +0000 (UTC) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.FreeBSD.org (Postfix) with ESMTP id 204CE43C9D for ; Mon, 4 Dec 2006 18:37:55 +0000 (GMT) (envelope-from millert@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kB4IcTxq090448 for ; Mon, 4 Dec 2006 18:38:29 GMT (envelope-from millert@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kB4IcSb4090445 for perforce@freebsd.org; Mon, 4 Dec 2006 18:38:28 GMT (envelope-from millert@freebsd.org) Date: Mon, 4 Dec 2006 18:38:28 GMT Message-Id: <200612041838.kB4IcSb4090445@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to millert@freebsd.org using -f From: Todd Miller To: Perforce Change Reviews Cc: Subject: PERFORCE change 111048 for review X-BeenThere: trustedbsd-cvs@FreeBSD.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: TrustedBSD CVS and Perforce commit message list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Dec 2006 18:38:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=111048 Change 111048 by millert@millert_g5tower on 2006/12/04 18:38:23 When logging avc audit info, fill in an array of struct audit_buffer which are later processed by audit_log_process() via sebsd_thread_userret(). This lets us log audit data without blocking during the actual syscall (atomic operations are used as needed). We use a spin lock to keep the printf()s from overlapping. Fixes a problem on dual CPU machines. Affected files ... .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.c#13 edit .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc_audit.c#3 edit .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/linux-compat.h#4 edit .. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#49 edit Differences ... ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.c#13 (text+ko) ==== @@ -270,7 +270,7 @@ lck_attr_setdefault(avc_lck_attr); /* no lock debugging */ /* allocate avc mutexes */ - avc_log_lock = lck_mtx_alloc_init(avc_lck_grp, avc_lck_attr); + avc_log_lock = lck_spin_alloc_init(avc_lck_grp, avc_lck_attr); notif_lock = lck_mtx_alloc_init(avc_lck_grp, avc_lck_attr); for (i = 0; i < AVC_CACHE_SLOTS; i++) { ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc_audit.c#3 (text+ko) ==== @@ -43,46 +43,80 @@ /* * Emulate Linux audit API. - * In the future we may wish to use the BSD audit support instead. - * TBD: use a freelist so we don't have to mallc/free so much. + * In the future we may wish to use the BSM audit support instead. */ -lck_mtx_t *avc_log_lock; - -extern void conslog_putc(char); - struct audit_buffer { struct sbuf sbuf; char buf[1024]; }; +#define AUDIT_SLOT_MAX 256 +static SInt32 nslots; +struct audit_buffer *audit_slots[AUDIT_SLOT_MAX]; + +lck_spin_t *avc_log_lock; + struct audit_buffer * audit_log_start(void) { struct audit_buffer *ab; ab = sebsd_malloc(sizeof(*ab), M_SEBSD, M_NOWAIT); - if (ab == NULL) { - printf("%s: unable to allocate audit buffer\n", __func__); - return (NULL); - } - sbuf_new(&ab->sbuf, ab->buf, sizeof(ab->buf), SBUF_FIXEDLEN); + if (ab != NULL) + sbuf_new(&ab->sbuf, ab->buf, sizeof(ab->buf), SBUF_FIXEDLEN); + return (ab); } void audit_log_end(struct audit_buffer *ab) { + int i; + UInt32 oldval; sbuf_finish(&ab->sbuf); - lck_mtx_lock(avc_log_lock); - printf("\n%s\n", sbuf_data(&ab->sbuf)); - lck_mtx_unlock(avc_log_lock); - sbuf_delete(&ab->sbuf); + + /* + * Find and claim an audit slot (assumes 32bit pointers). + */ + for (i = 0; i < AUDIT_SLOT_MAX; i++) { + oldval = (UInt32)audit_slots[i]; + if (oldval == 0 && OSCompareAndSwap(oldval, (UInt32)ab, + (UInt32 *)&audit_slots[i])) { + OSIncrementAtomic(&nslots); + return; + } + } + /* No free slots, drop record. */ sebsd_free(ab, M_SEBSD); } void +audit_log_process(void) +{ + struct audit_buffer *ab; + int i; + + /* + * Print and free all existing (finished) audit records. + */ + lck_spin_lock(avc_log_lock); + for (i = 0; nslots != 0 && i < AUDIT_SLOT_MAX; i++) { + ab = audit_slots[i]; + if (ab != NULL) { + if (OSCompareAndSwap((UInt32)ab, 0, + (UInt32 *)&audit_slots[i])) { + OSDecrementAtomic(&nslots); + printf("\n%s\n", sbuf_data(&ab->sbuf)); + sebsd_free(ab, M_SEBSD); + } + } + } + lck_spin_unlock(avc_log_lock); +} + +void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) { va_list ap; @@ -93,8 +127,21 @@ } void +_audit_log(const char *fmt, ...) +{ + struct audit_buffer *ab; + va_list ap; + + ab = audit_log_start(); + va_start(ap, fmt); + sbuf_vprintf(&ab->sbuf, fmt, ap); + va_end(ap); + audit_log_end(ab); +} + +void audit_log_untrustedstring(struct audit_buffer *ab, const char *s) { - sbuf_cat(&ab->sbuf, s); + sbuf_cat(&ab->sbuf, s); /* XXX - wants vis(3) support */ } ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/linux-compat.h#4 (text+ko) ==== @@ -135,18 +135,15 @@ #define TUNABLE_INT_FETCH(str,var) /* emulate linux audit support */ -extern lck_mtx_t *avc_log_lock; +extern lck_spin_t *avc_log_lock; struct audit_buffer; struct audit_buffer *audit_log_start(void); +void _audit_log(const char *, ...); void audit_log_end(struct audit_buffer *); void audit_log_format(struct audit_buffer *, const char *, ...); void audit_log_untrustedstring(struct audit_buffer *, const char *); -#define audit_log(ac, mf, af, ...) do { \ - lck_mtx_lock(avc_log_lock); \ - printf(__VA_ARGS__); \ - printf("\n"); \ - lck_mtx_unlock(avc_log_lock); \ -} while (0) +void audit_log_process(void); +#define audit_log(ac, mf, af, ...) _audit_log(__VA_ARGS__) /* we don't enable the selinux netlbl support */ #define selinux_netlbl_cache_invalidate() ==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/sebsd.c#49 (text+ko) ==== @@ -3527,6 +3527,14 @@ return (ipc_has_perm(cred, pshmlabel, SHM__DESTROY)); } +static void +sebsd_thread_userret(struct thread *thread) +{ + + /* Process any pending audit log records at syscall exit. */ + audit_log_process(); +} + static struct mac_policy_ops sebsd_ops = { .mpo_cred_check_label_update =sebsd_cred_check_label_update, .mpo_cred_check_label_update_execve = sebsd_cred_check_label_update_execve, @@ -3706,6 +3714,7 @@ .mpo_task_label_init = sebsd_cred_label_init, .mpo_task_label_internalize = sebsd_cred_label_internalize, .mpo_task_label_update = sebsd_task_label_update, + .mpo_thread_userret = sebsd_thread_userret, .mpo_vnode_check_access = sebsd_vnode_check_access, .mpo_vnode_check_chdir = sebsd_vnode_check_chdir, .mpo_vnode_check_chroot = sebsd_vnode_check_chroot,