[SRU][Trusty[[PATCH 1/1] audit: stop an old auditd being starved out by a new auditd

Joseph Salisbury joseph.salisbury at canonical.com
Thu Nov 10 17:24:09 UTC 2016


From: Richard Guy Briggs <rgb at redhat.com>

BugLink: http://bugs.launchpad.net/bugs/1633404

Nothing prevents a new auditd starting up and replacing a valid
audit_pid when an old auditd is still running, effectively starving out
the old auditd since audit_pid no longer points to the old valid
auditd.

If no message to auditd has been attempted since auditd died
unnaturally or got killed, audit_pid will still indicate it is alive.
There isn't an easy way to detect if an old auditd is still running on
the existing audit_pid other than attempting to send a message to see
if it fails.  An -ECONNREFUSED almost certainly means it disappeared
and can be replaced.  Other errors are not so straightforward and may
indicate transient problems that will resolve themselves and the old
auditd will recover.  Yet others will likely need manual intervention
for which a new auditd will not solve the problem.

Send a new message type (AUDIT_REPLACE) to the old auditd containing a
u32 with the PID of the new auditd.  If the audit replace message
succeeds (or doesn't fail with certainty), fail to register the new
auditd and return an error (-EEXIST).

This is expected to make the patch preventing an old auditd orphaning a
new auditd redundant.

V3: Switch audit message type from 1000 to 1300 block.

Signed-off-by: Richard Guy Briggs <rgb at redhat.com>
Signed-off-by: Paul Moore <pmoore at redhat.com>
(backported from commit 133e1e5acd4a63c4a0dcc413e90d5decdbce9c4a)
Signed-off-by: Joseph Salisbury <joseph.salisbury at canonical.com>
---
 include/uapi/linux/audit.h |  1 +
 kernel/audit.c             | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 44b05a0..8cf532a 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -109,6 +109,7 @@
 #define AUDIT_NETFILTER_PKT	1324	/* Packets traversing netfilter chains */
 #define AUDIT_NETFILTER_CFG	1325	/* Netfilter chain modifications */
 #define AUDIT_SECCOMP		1326	/* Secure Computing event */
+#define AUDIT_REPLACE		1329	/* Replace auditd if this packet unanswerd */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
diff --git a/kernel/audit.c b/kernel/audit.c
index 013d900..7594745 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -729,6 +729,16 @@ static int audit_set_feature(struct sk_buff *skb)
 	return 0;
 }
 
+static int audit_replace(pid_t pid)
+{
+	struct sk_buff *skb = audit_make_reply(0, 0, AUDIT_REPLACE, 0, 0,
+					       &pid, sizeof(pid));
+
+	if (!skb)
+		return -ENOMEM;
+	return netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
+}
+
 static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	u32			seq;
@@ -787,7 +797,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 		}
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int new_pid = status_get->pid;
+			pid_t requesting_pid = task_tgid_vnr(current);
 
+			if ((!new_pid) && (requesting_pid != audit_pid))
+				return -EACCES;
+			if (audit_pid && new_pid &&
+			    audit_replace(requesting_pid) != -ECONNREFUSED)
+				return -EEXIST;
 			if (audit_enabled != AUDIT_OFF)
 				audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
 			audit_pid = new_pid;
-- 
2.7.4





More information about the kernel-team mailing list