<div dir="ltr">This need came about in Samsung's mobile products. Id like to see and attempt to get this mainstreamed. Any feedback would be greatly appreciated. Thanks.</div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, May 22, 2013 at 7:16 PM, William Roberts <span dir="ltr"><<a href="mailto:bill.c.roberts@gmail.com" target="_blank">bill.c.roberts@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Allow the audit subsystem to send audit events to both the kernel<br>
message buffer and auditd at the same time.<br>
<br>
Signed-off-by: William Roberts <<a href="mailto:w.roberts@sta.samsung.com">w.roberts@sta.samsung.com</a>><br>
---<br>
 include/uapi/linux/audit.h | 11 ++++++++++<br>
 init/Kconfig               |  8 +++++++<br>
 kernel/audit.c             | 52 ++++++++++++++++++++++++++++++++++++++++------<br>
 kernel/audit.h             |  6 ++++++<br>
 4 files changed, 71 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h<br>
index 75cef3f..0af5d78 100644<br>
--- a/include/uapi/linux/audit.h<br>
+++ b/include/uapi/linux/audit.h<br>
@@ -68,6 +68,8 @@<br>
 #define AUDIT_MAKE_EQUIV       1015    /* Append to watched tree */<br>
 #define AUDIT_TTY_GET          1016    /* Get TTY auditing status */<br>
 #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */<br>
+#define AUDIT_LOGSPLIT_GET      1018    /* Get logsplit status */<br>
+#define AUDIT_LOGSPLIT_SET      1019    /* Set logsplit status */<br>
<br>
 #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */<br>
 #define AUDIT_USER_AVC         1107    /* We filter this differently */<br>
@@ -321,6 +323,10 @@ enum {<br>
 #define AUDIT_FAIL_PRINTK      1<br>
 #define AUDIT_FAIL_PANIC       2<br>
<br>
+/* Audit splitlog options */<br>
+#define AUDIT_LOGSPLIT_OFF     0<br>
+#define AUDIT_LOGSPLIT_ON      1<br>
+<br>
 /* distinguish syscall tables */<br>
 #define __AUDIT_ARCH_64BIT 0x80000000<br>
 #define __AUDIT_ARCH_LE           0x40000000<br>
@@ -374,6 +380,11 @@ struct audit_tty_status {<br>
        __u32           log_passwd;     /* 1 = enabled, 0 = disabled */<br>
 };<br>
<br>
+struct audit_logsplit_status {<br>
+       __u32           enabled;        /* AUDIT_LOGSPLIT_ON or<br>
+                                               AUDIT_LOGSPLIT_OFF */<br>
+};<br>
+<br>
 /* audit_rule_data supports filter rules with both integer and string<br>
  * fields.  It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and<br>
  * AUDIT_LIST_RULES requests.<br>
diff --git a/init/Kconfig b/init/Kconfig<br>
index 9d3a788..52efca6 100644<br>
--- a/init/Kconfig<br>
+++ b/init/Kconfig<br>
@@ -286,6 +286,14 @@ config AUDIT_LOGINUID_IMMUTABLE<br>
          one to drop potentially dangerous capabilites from the login tasks,<br>
          but may not be backwards compatible with older init systems.<br>
<br>
+config AUDIT_SPLITLOG<br>
+       bool "Split audit messages to userspace and kernel by default"<br>
+       depends on AUDIT<br>
+       help<br>
+         Setting this to true will cause the audit messages to be split<br>
+         by default to both the kernel message log and a userspace audit<br>
+         daemon if registered.<br>
+<br>
 source "kernel/irq/Kconfig"<br>
 source "kernel/time/Kconfig"<br>
<br>
diff --git a/kernel/audit.c b/kernel/audit.c<br>
index 21c7fa6..ccd2f60 100644<br>
--- a/kernel/audit.c<br>
+++ b/kernel/audit.c<br>
@@ -88,6 +88,9 @@ static int    audit_default;<br>
 /* If auditing cannot proceed, audit_failure selects what happens. */<br>
 static int     audit_failure = AUDIT_FAIL_PRINTK;<br>
<br>
+/* Whether or not logsplit is enabled */<br>
+static int audit_logsplit = AUDIT_SPLITLOG_INIT;<br>
+<br>
 /*<br>
  * If audit records are to be written to the netlink socket, audit_pid<br>
  * contains the pid of the auditd process and audit_nlk_portid contains<br>
@@ -343,6 +346,17 @@ static int audit_set_failure(int state)<br>
        return audit_do_config_change("audit_failure", &audit_failure, state);<br>
 }<br>
<br>
+static int audit_set_logsplit(int state)<br>
+{<br>
+       if (state != AUDIT_LOGSPLIT_OFF<br>
+               && state != AUDIT_LOGSPLIT_ON)<br>
+               return -EINVAL;<br>
+<br>
+       return audit_do_config_change("audit_logsplit", &audit_logsplit, state);<br>
+}<br>
+<br>
+<br>
+<br>
 /*<br>
  * Queue skbs to be sent to auditd when/if it comes back.  These skbs should<br>
  * already have been sent via prink/syslog and so if these messages are dropped<br>
@@ -361,11 +375,8 @@ static void audit_hold_skb(struct sk_buff *skb)<br>
                kfree_skb(skb);<br>
 }<br>
<br>
-/*<br>
- * For one reason or another this nlh isn't getting delivered to the userspace<br>
- * audit daemon, just send it to printk.<br>
- */<br>
-static void audit_printk_skb(struct sk_buff *skb)<br>
+/* Just printks the skb, no audit_hold or free of any kind */<br>
+static void __audit_printk_skb(struct sk_buff *skb)<br>
 {<br>
        struct nlmsghdr *nlh = nlmsg_hdr(skb);<br>
        char *data = nlmsg_data(nlh);<br>
@@ -376,7 +387,14 @@ static void audit_printk_skb(struct sk_buff *skb)<br>
                else<br>
                        audit_log_lost("printk limit exceeded\n");<br>
        }<br>
-<br>
+}<br>
+/*<br>
+ * For one reason or another this nlh isn't getting delivered to the userspace<br>
+ * audit daemon, just send it to printk.<br>
+ */<br>
+static void audit_printk_skb(struct sk_buff *skb)<br>
+{<br>
+       __audit_printk_skb(skb);<br>
        audit_hold_skb(skb);<br>
 }<br>
<br>
@@ -590,6 +608,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)<br>
        case AUDIT_SIGNAL_INFO:<br>
        case AUDIT_TTY_GET:<br>
        case AUDIT_TTY_SET:<br>
+       case AUDIT_LOGSPLIT_GET:<br>
+       case AUDIT_LOGSPLIT_SET:<br>
        case AUDIT_TRIM:<br>
        case AUDIT_MAKE_EQUIV:<br>
                if (!capable(CAP_AUDIT_CONTROL))<br>
@@ -843,7 +863,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)<br>
                spin_unlock(&tsk->sighand->siglock);<br>
                break;<br>
        }<br>
+       case AUDIT_LOGSPLIT_GET: {<br>
+               struct audit_logsplit_status s;<br>
+               s.enabled = audit_logsplit;<br>
+               audit_send_reply(NETLINK_CB(skb).portid, seq,<br>
+                       AUDIT_LOGSPLIT_GET, 0, 0, &s, sizeof(s));<br>
+               break;<br>
+       }<br>
+       case AUDIT_LOGSPLIT_SET: {<br>
+               struct audit_logsplit_status *s;<br>
+               if (nlh->nlmsg_len < sizeof(struct audit_logsplit_status))<br>
+                       return -EINVAL;<br>
+               s = data;<br>
+               err = audit_set_logsplit(s->enabled);<br>
+               break;<br>
+       }<br>
+<br>
        default:<br>
+               printk(KERN_ERR "Unkown audit command");<br>
                err = -EINVAL;<br>
                break;<br>
        }<br>
@@ -1670,6 +1707,9 @@ void audit_log_end(struct audit_buffer *ab)<br>
                nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;<br>
<br>
                if (audit_pid) {<br>
+                       if (audit_logsplit == AUDIT_LOGSPLIT_ON)<br>
+                                __audit_printk_skb(ab->skb);<br>
+<br>
                        skb_queue_tail(&audit_skb_queue, ab->skb);<br>
                        wake_up_interruptible(&kauditd_wait);<br>
                } else {<br>
diff --git a/kernel/audit.h b/kernel/audit.h<br>
index 1c95131..ef43bb1 100644<br>
--- a/kernel/audit.h<br>
+++ b/kernel/audit.h<br>
@@ -321,4 +321,10 @@ extern struct list_head *audit_killed_trees(void);<br>
 #define audit_filter_inodes(t,c) AUDIT_DISABLED<br>
 #endif<br>
<br>
+#ifdef CONFIG_AUDIT_SPLITLOG<br>
+#define AUDIT_SPLITLOG_INIT AUDIT_LOGSPLIT_ON<br>
+#else<br>
+#define AUDIT_SPLITLOG_INIT AUDIT_LOGSPLIT_OFF<br>
+#endif<br>
+<br>
 extern struct mutex audit_cmd_mutex;<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.2.2<br>
<br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br>Respectfully,<br><br>William C Roberts<br><br>
</div>