Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Dec 2006 18:38:28 GMT
From:      Todd Miller <millert@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 111048 for review
Message-ID:  <200612041838.kB4IcSb4090445@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612041838.kB4IcSb4090445>