[PATCH] Enable splitting the logs to both auditd and kernel simultaneously

William Roberts bill.c.roberts at gmail.com
Mon May 20 22:03:52 UTC 2013


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

Signed-off-by: William Roberts <w.roberts at sta.samsung.com>
---
 include/uapi/linux/audit.h | 11 ++++++++++
 init/Kconfig               |  8 +++++++
 kernel/audit.c             | 52 ++++++++++++++++++++++++++++++++++++++++------
 kernel/audit.h             |  6 ++++++
 4 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 75cef3f..0af5d78 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -68,6 +68,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 */
@@ -321,6 +323,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
@@ -374,6 +380,11 @@ struct audit_tty_status {
 	__u32		log_passwd;	/* 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/init/Kconfig b/init/Kconfig
index 9d3a788..52efca6 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -286,6 +286,14 @@ config AUDIT_LOGINUID_IMMUTABLE
 	  one to drop potentially dangerous capabilites from the login tasks,
 	  but may not be backwards compatible with older init systems.
 
+config AUDIT_SPLITLOG
+       bool "Split audit messages to userspace and kernel by default"
+       depends on AUDIT
+       help
+         Setting this to true will cause the audit messages to be split
+         by default to both the kernel message log and a userspace audit
+         daemon if registered.
+
 source "kernel/irq/Kconfig"
 source "kernel/time/Kconfig"
 
diff --git a/kernel/audit.c b/kernel/audit.c
index 21c7fa6..ccd2f60 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -88,6 +88,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_SPLITLOG_INIT;
+
 /*
  * If audit records are to be written to the netlink socket, audit_pid
  * contains the pid of the auditd process and audit_nlk_portid contains
@@ -343,6 +346,17 @@ static int audit_set_failure(int state)
 	return audit_do_config_change("audit_failure", &audit_failure, state);
 }
 
+static int audit_set_logsplit(int state)
+{
+	if (state != AUDIT_LOGSPLIT_OFF
+		&& state != AUDIT_LOGSPLIT_ON)
+		return -EINVAL;
+
+	return audit_do_config_change("audit_logsplit", &audit_logsplit, state);
+}
+
+
+
 /*
  * 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
@@ -361,11 +375,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);
@@ -376,7 +387,14 @@ static void audit_printk_skb(struct sk_buff *skb)
 		else
 			audit_log_lost("printk limit exceeded\n");
 	}
-
+}
+/*
+ * 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);
 }
 
@@ -590,6 +608,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))
@@ -843,7 +863,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 		spin_unlock(&tsk->sighand->siglock);
 		break;
 	}
+	case AUDIT_LOGSPLIT_GET: {
+		struct audit_logsplit_status s;
+		s.enabled = audit_logsplit;
+		audit_send_reply(NETLINK_CB(skb).portid, 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);
+		break;
+	}
+
 	default:
+		printk(KERN_ERR "Unkown audit command");
 		err = -EINVAL;
 		break;
 	}
@@ -1670,6 +1707,9 @@ void audit_log_end(struct audit_buffer *ab)
 		nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
 
 		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 {
diff --git a/kernel/audit.h b/kernel/audit.h
index 1c95131..ef43bb1 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -321,4 +321,10 @@ extern struct list_head *audit_killed_trees(void);
 #define audit_filter_inodes(t,c) AUDIT_DISABLED
 #endif
 
+#ifdef CONFIG_AUDIT_SPLITLOG
+#define AUDIT_SPLITLOG_INIT AUDIT_LOGSPLIT_ON
+#else
+#define AUDIT_SPLITLOG_INIT AUDIT_LOGSPLIT_OFF
+#endif
+
 extern struct mutex audit_cmd_mutex;
-- 
1.8.2.2




More information about the Linux-audit mailing list