Allow the audit subsystem to send audit events to both the kernel
message buffer and auditd at the same time.

Change-Id: I53de6b121bb4d7ec0cd31fa9b7a9d31a1ff9782f
Signed-off-by: William Roberts <[email protected]>
---
 include/linux/audit.h | 10 ++++++++++
 kernel/audit.c        | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index ed3ef19..cbc7582 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -69,6 +69,8 @@
 #define AUDIT_MAKE_EQUIV       1015    /* Append to watched tree */
 #define AUDIT_TTY_GET          1016    /* Get TTY auditing status */
 #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
+#define AUDIT_LOGSPLIT_GET     1018    /* Get logsplit status */
+#define AUDIT_LOGSPLIT_SET     1019    /* Set logsplit status */
 
 #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly 
uninteresting to kernel */
 #define AUDIT_USER_AVC         1107    /* We filter this differently */
@@ -319,6 +321,10 @@ enum {
 #define AUDIT_FAIL_PRINTK      1
 #define AUDIT_FAIL_PANIC       2
 
+/* Audit splitlog options */
+#define AUDIT_LOGSPLIT_OFF     0
+#define AUDIT_LOGSPLIT_ON      1
+
 /* distinguish syscall tables */
 #define __AUDIT_ARCH_64BIT 0x80000000
 #define __AUDIT_ARCH_LE           0x40000000
@@ -370,6 +376,10 @@ struct audit_tty_status {
        __u32           enabled; /* 1 = enabled, 0 = disabled */
 };
 
+struct audit_logsplit_status {
+       __u32           enabled; /* AUDIT_LOGSPLIT_ON or AUDIT_LOGSPLIT_OFF */
+};
+
 /* audit_rule_data supports filter rules with both integer and string
  * fields.  It corresponds with AUDIT_ADD_RULE, AUDIT_DEL_RULE and
  * AUDIT_LIST_RULES requests.
diff --git a/kernel/audit.c b/kernel/audit.c
index 4096bcc..b970a91 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -85,6 +85,9 @@ static int    audit_default;
 /* If auditing cannot proceed, audit_failure selects what happens. */
 static int     audit_failure = AUDIT_FAIL_PRINTK;
 
+/* Whether or not logsplit is enabled */
+static int audit_logsplit = AUDIT_LOGSPLIT_OFF;
+
 /*
  * If audit records are to be written to the netlink socket, audit_pid
  * contains the pid of the auditd process and audit_nlk_pid contains
@@ -357,6 +360,16 @@ static int audit_set_failure(int state, uid_t loginuid, 
u32 sessionid, u32 sid)
                                      loginuid, sessionid, sid);
 }
 
+static int audit_set_logsplit(int state, uid_t loginuid, u32 sessionid, u32 
sid)
+{
+       if (state != AUDIT_LOGSPLIT_OFF
+                       && state != AUDIT_LOGSPLIT_ON)
+               return -EINVAL;
+
+       return audit_do_config_change("audit_logsplit", &audit_logsplit, state,
+                                     loginuid, sessionid, sid);
+}
+
 /*
  * Queue skbs to be sent to auditd when/if it comes back.  These skbs should
  * already have been sent via prink/syslog and so if these messages are dropped
@@ -375,11 +388,8 @@ static void audit_hold_skb(struct sk_buff *skb)
                kfree_skb(skb);
 }
 
-/*
- * For one reason or another this nlh isn't getting delivered to the userspace
- * audit daemon, just send it to printk.
- */
-static void audit_printk_skb(struct sk_buff *skb)
+/* Just printks the skb, no audit_hold or free of any kind */
+static void __audit_printk_skb(struct sk_buff *skb)
 {
        struct nlmsghdr *nlh = nlmsg_hdr(skb);
        char *data = NLMSG_DATA(nlh);
@@ -387,7 +397,15 @@ static void audit_printk_skb(struct sk_buff *skb)
        if (nlh->nlmsg_type != AUDIT_EOE) {
                printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data);
        }
+}
 
+/*
+ * For one reason or another this nlh isn't getting delivered to the userspace
+ * audit daemon, just send it to printk.
+ */
+static void audit_printk_skb(struct sk_buff *skb)
+{
+       __audit_printk_skb(skb);
        audit_hold_skb(skb);
 }
 
@@ -594,6 +612,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 
msg_type)
        case AUDIT_SIGNAL_INFO:
        case AUDIT_TTY_GET:
        case AUDIT_TTY_SET:
+       case AUDIT_LOGSPLIT_GET:
+       case AUDIT_LOGSPLIT_SET:
        case AUDIT_TRIM:
        case AUDIT_MAKE_EQUIV:
                if (!capable(CAP_AUDIT_CONTROL))
@@ -909,7 +929,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
                rcu_read_unlock();
                break;
        }
+       case AUDIT_LOGSPLIT_GET: {
+               struct audit_logsplit_status s;
+               s.enabled = audit_logsplit;
+               audit_send_reply(NETLINK_CB(skb).pid, seq,
+                               AUDIT_LOGSPLIT_GET, 0, 0, &s, sizeof(s));
+               break;
+       }
+       case AUDIT_LOGSPLIT_SET: {
+               struct audit_logsplit_status *s;
+               if (nlh->nlmsg_len < sizeof(struct audit_logsplit_status))
+                       return -EINVAL;
+               s = data;
+               err = audit_set_logsplit(s->enabled, loginuid, sessionid, sid);
+               break;
+       }
+
        default:
+               printk(KERN_ERR "Unknown audit command");
                err = -EINVAL;
                break;
        }
@@ -1464,6 +1501,8 @@ void audit_log_end(struct audit_buffer *ab)
                nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
 
                if (audit_pid) {
+                       if (audit_logsplit == AUDIT_LOGSPLIT_ON)
+                               __audit_printk_skb(ab->skb);
                        skb_queue_tail(&audit_skb_queue, ab->skb);
                        wake_up_interruptible(&kauditd_wait);
                } else {
-- 
1.8.2.2


--
This message was distributed to subscribers of the seandroid-list mailing list.
If you no longer wish to subscribe, send mail to [email protected] with
the words "unsubscribe seandroid-list" without quotes as the message.

Reply via email to