Log information about programs connecting and disconnecting to the audit
netlink multicast socket. This is needed so that during investigations a
security officer can tell who or what had access to the audit trail. This
helps to meet the FAU_SAR.2 requirement for Common Criteria.
Signed-off-by: Steve Grubb <sgrubb(a)redhat.com>
---
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 30 ++++++++++++++++++++++++++++--
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index d3475e1..bb4555a 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -110,6 +110,7 @@
#define AUDIT_SECCOMP 1326 /* Secure Computing event */
#define AUDIT_PROCTITLE 1327 /* Proctitle emit event */
#define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */
+#define AUDIT_EVENT_LISTENER 1329 /* task joined multicast read socket */
#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 29fb38b..3253f1b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1135,13 +1135,36 @@ void audit_log_task_simple(struct audit_buffer *ab, struct
task_struct *tsk)
}
EXPORT_SYMBOL(audit_log_task_simple);
+static void audit_log_bind(int group, const char *op, int err)
+{
+ struct audit_buffer *ab;
+
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_EVENT_LISTENER);
+ if (!ab)
+ return;
+
+ audit_log_task_simple(ab, current);
+ audit_log_format(ab, " nlnk-grp=%d", group);
+ audit_log_format(ab, " op=%s", op);
+ audit_log_format(ab, " res=%d", !err);
+ audit_log_end(ab);
+}
+
/* Run custom bind function on netlink socket group connect or bind requests. */
static int audit_bind(struct net *net, int group)
{
+ int err = 0;
+
if (!capable(CAP_AUDIT_READ))
- return -EPERM;
+ err = -EPERM;
+ audit_log_bind(group, "connect", err);
- return 0;
+ return err;
+}
+
+static void audit_unbind(struct net *net, int group)
+{
+ audit_log_bind(group, "disconnect", 0);
}
static int __net_init audit_net_init(struct net *net)
@@ -1151,6 +1176,7 @@ static int __net_init audit_net_init(struct net *net)
.bind = audit_bind,
.flags = NL_CFG_F_NONROOT_RECV,
.groups = AUDIT_NLGRP_MAX,
+ .unbind = audit_unbind,
};
struct audit_net *aunet = net_generic(net, audit_net_id);
--
2.4.3