PERFORCE change 113365 for review
Todd Miller
millert at FreeBSD.org
Mon Jan 22 16:25:02 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=113365
Change 113365 by millert at millert_macbook on 2007/01/22 16:24:15
We can't hold the spinlock to protect the avc log printf()
for as long as we do since vn_getpath() may sleep. Go back
to allocating a new log struct for each avc audit message
and only hold the spinlock for the duration of the printf(),
which is safe. As an optimization, keep a spare log struct
to avoid allocating when we don't need to (and since we
are not allowed to sleep).
Affected files ...
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.c#19 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.h#9 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc_audit.c#6 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/linux-compat.h#7 edit
Differences ...
==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.c#19 (text+ko) ====
@@ -270,10 +270,11 @@
lck_attr_setdefault(avc_lck_attr); /* no lock debugging */
/* allocate avc locks */
- avc_log_lock = lck_spin_alloc_init(avc_lck_grp, avc_lck_attr);
avc_lock = lck_rw_alloc_init(avc_lck_grp, avc_lck_attr);
notif_lock = lck_spin_alloc_init(avc_lck_grp, avc_lck_attr);
+ avc_audit_init(avc_lck_grp, avc_lck_attr);
+
for (i = 0; i < AVC_CACHE_SLOTS; i++) {
LIST_INIT(&avc_cache.slots[i]);
}
@@ -603,7 +604,7 @@
return;
}
- ab = audit_log_start();
+ ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc.h#9 (text+ko) ====
@@ -140,5 +140,7 @@
DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats);
#endif
+void avc_audit_init(lck_grp_t *avc_lck_grp, lck_attr_t *avc_lck_attr);
+
#endif /* _SELINUX_AVC_H_ */
==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/avc/avc_audit.c#6 (text+ko) ====
@@ -38,8 +38,10 @@
#include <kern/lock.h>
#include <security/mac_policy.h>
+#include <security/mac_alloc.h>
#include <sedarwin/linux-compat.h>
#include <sedarwin/sebsd.h>
+#include <sedarwin/avc/avc.h>
/*
* Emulate Linux audit API.
@@ -52,16 +54,40 @@
struct sbuf sbuf;
char buf[1024];
};
-static struct audit_buffer audit_buf;
+
+static zone_t avc_audit_zone; /* audit buffer zone */
+static struct audit_buffer *spare_buf; /* spare buffer */
+
+void
+avc_audit_init(lck_grp_t *avc_lck_grp, lck_attr_t *avc_lck_attr)
+{
+
+ avc_log_lock = lck_spin_alloc_init(avc_lck_grp, avc_lck_attr);
+ avc_audit_zone = mac_zinit(sizeof(struct audit_buffer),
+ 512 * sizeof(struct audit_buffer), 0, "avc_audit");
+ spare_buf = mac_zalloc(avc_audit_zone, M_WAITOK);
+}
struct audit_buffer *
-audit_log_start(void)
+_audit_log_start(int flag)
{
+ struct audit_buffer *ab = spare_buf;
- lck_spin_lock(avc_log_lock);
- sbuf_new(&audit_buf.sbuf, audit_buf.buf, sizeof(audit_buf.buf),
- SBUF_FIXEDLEN);
- return (&audit_buf);
+ /* Use a free buffer if available, else alloc a new one. */
+ if (ab != NULL) {
+ if (OSCompareAndSwap((UInt32)ab, 0, (UInt32 *)&spare_buf) == 0)
+ ab = NULL;
+ }
+ if (ab == NULL) {
+ ab = mac_zalloc(avc_audit_zone, flag);
+ 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);
+ return (ab);
}
void
@@ -69,9 +95,13 @@
{
sbuf_finish(&ab->sbuf);
+ lck_spin_lock(avc_log_lock);
printf("\n%s\n", sbuf_data(&ab->sbuf));
- sbuf_delete(&ab->sbuf); /* XXX - not really needed */
lck_spin_unlock(avc_log_lock);
+ /* Always keep a free buffer around. */
+ if (spare_buf != NULL ||
+ OSCompareAndSwap(0, (UInt32)ab, (UInt32 *)&spare_buf) == 0)
+ mac_zfree(avc_audit_zone, ab);
}
void
@@ -85,19 +115,6 @@
}
void
-sebsd_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)
{
==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/linux-compat.h#7 (text+ko) ====
@@ -137,12 +137,18 @@
/* emulate linux audit support */
extern lck_spin_t *avc_log_lock;
struct audit_buffer;
-struct audit_buffer *audit_log_start(void);
-void sebsd_log(const char *, ...);
+struct audit_buffer *_audit_log_start(int);
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, ...) sebsd_log(__VA_ARGS__)
+#define audit_log_start(ac, mf, af) _audit_log_start(mf)
+#define audit_log(ac, mf, af, ...) do { \
+ lck_spin_lock(avc_log_lock); \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
+ lck_spin_unlock(avc_log_lock); \
+} while (0)
+#define sebsd_log(fmt, ...) printf(fmt "\n", __VA_ARGS__)
/* we don't enable the selinux netlbl support */
#define selinux_netlbl_cache_invalidate()
More information about the trustedbsd-cvs
mailing list