(forw) [PATCH] LSM hooks for audit

Serge E. Hallyn serue at us.ibm.com
Wed Sep 15 14:15:29 UTC 2004


----- Forwarded message from Serge Hallyn <serue at us.ibm.com> -----

From: Serge Hallyn <serue at us.ibm.com>
To: LSM <linux-security-module at wirex.com>
Message-Id: <1095256778.5294.17.camel at serge.austin.ibm.com>
X-Mailer: Ximian Evolution 1.4.5 
Date: Wed, 15 Sep 2004 08:59:38 -0500
Cc: 
Subject: [PATCH] LSM hooks for audit

Hi,

Attached is a patch which provides LSM controls over actions related to
the new audit framework.  As a specific example, we might like to have
an "audit role", enabled by selinux or some other LSM, which would be
the only role allowed to add or delete filter rules.

What do people think about adding these hooks, both in general and these
hooks specifically?

thanks,
-serge

-- 
=======================================================
Serge Hallyn
Security Software Engineer, IBM Linux Technology Center
serue at us.ibm.com

diff -pNru /home/hallyn/kernels/linux-2.6.8.1/include/linux/security.h linux-2.6.8.1/include/linux/security.h
--- /home/hallyn/kernels/linux-2.6.8.1/include/linux/security.h	2004-08-14 05:55:48.000000000 -0500
+++ linux-2.6.8.1/include/linux/security.h	2004-09-09 11:27:25.661860264 -0500
@@ -1012,6 +1012,22 @@ struct swap_info_struct;
  *	remove a stacked module.
  *	@name contains the name of the security module being unstacked.
  *	@ops contains a pointer to the struct security_operations of the module to unstack.
+ * @audit_set:
+ *	set login parameters
+ *	@mask: list of what is being set, out of
+ *		AUDIT_STATUS_ENABLED
+ *		AUDIT_STATUS_FAILURE
+ *		AUDIT_STATUS_PID
+ *		AUDIT_STATUS_RATE_LIMIT
+ *		AUDIT_STATUS_BACKLOG_LIMIT
+ * @audit_login:
+ *	create a login audit record
+ * @audit_listfilter:
+ *	list the syscall audit rules
+ * @audit_listadd:
+ *	add a syscall audit rule
+ * @audit_listdel:
+ *	delete a syscall audit rule
  * 
  * This is the main security structure.
  */
@@ -1228,6 +1244,12 @@ struct security_operations {
 	int (*sk_alloc_security) (struct sock *sk, int family, int priority);
 	void (*sk_free_security) (struct sock *sk);
 #endif	/* CONFIG_SECURITY_NETWORK */
+
+	int (*audit_set) (u32 mask);
+	int (*audit_login) (void);
+	int (*audit_listfilter) (void);
+	int (*audit_listadd) (void);
+	int (*audit_listdel) (void);
 };
 
 /* global variables */
@@ -1876,6 +1898,31 @@ static inline int security_setprocattr(s
 	return security_ops->setprocattr(p, name, value, size);
 }
 
+static inline int security_audit_set (u32 mask)
+{
+	return security_ops->audit_set(mask);
+}
+
+static inline int security_audit_login (void)
+{
+	return security_ops->audit_login();
+}
+
+static inline int security_audit_listfilter (void)
+{
+	return security_ops->audit_listfilter();
+}
+
+static inline int security_audit_listadd (void)
+{
+	return security_ops->audit_listadd();
+}
+
+static inline int security_audit_listdel (void)
+{
+	return security_ops->audit_listdel();
+}
+
 static inline int security_netlink_send(struct sock *sk, struct sk_buff * skb)
 {
 	return security_ops->netlink_send(sk, skb);
@@ -2499,6 +2546,31 @@ static inline int security_setprocattr(s
 	return -EINVAL;
 }
 
+int security_audit_set (u32 mask)
+{
+	return 0;
+}
+
+int security_audit_login (void)
+{
+	return 0;
+}
+
+int security_audit_listfilter (void)
+{
+	return 0;
+}
+
+int security_audit_listadd (void)
+{
+	return 0;
+}
+
+int security_audit_listdel (void)
+{
+	return 0;
+}
+
 /*
  * The netlink capability defaults need to be used inline by default
  * (rather than hooking into the capability module) to reduce overhead
diff -pNru /home/hallyn/kernels/linux-2.6.8.1/kernel/audit.c linux-2.6.8.1/kernel/audit.c
--- /home/hallyn/kernels/linux-2.6.8.1/kernel/audit.c	2004-08-14 05:56:24.000000000 -0500
+++ linux-2.6.8.1/kernel/audit.c	2004-09-09 10:51:18.636298224 -0500
@@ -327,8 +327,9 @@ static int audit_receive_msg(struct sk_b
 				 &status_set, sizeof(status_set));
 		break;
 	case AUDIT_SET:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
+		err = security_audit_set(status_get->mask);
+		if (err)
+			return err;
 		status_get   = (struct audit_status *)data;
 		if (status_get->mask & AUDIT_STATUS_ENABLED) {
 			err = audit_set_enabled(status_get->enabled);
@@ -364,8 +365,9 @@ static int audit_receive_msg(struct sk_b
 		audit_log_end(ab);
 		break;
 	case AUDIT_LOGIN:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
+		err = security_audit_login();
+		if (err)
+			return err;
 		login = (struct audit_login *)data;
 		ab = audit_log_start(NULL);
 		if (ab) {
diff -pNru /home/hallyn/kernels/linux-2.6.8.1/kernel/auditsc.c linux-2.6.8.1/kernel/auditsc.c
--- /home/hallyn/kernels/linux-2.6.8.1/kernel/auditsc.c	2004-08-14 05:55:48.000000000 -0500
+++ linux-2.6.8.1/kernel/auditsc.c	2004-09-09 11:37:43.176983696 -0500
@@ -34,6 +34,7 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/security.h>
 
 #include <linux/audit.h>
 #include <linux/personality.h>
@@ -238,6 +239,9 @@ int audit_receive_filter(int type, int p
 	case AUDIT_LIST:
 		/* The *_rcu iterators not needed here because we are
 		   always called with audit_netlink_sem held. */
+		err = security_audit_listfilter();
+		if (err)
+			return err;
 		list_for_each_entry(entry, &audit_tsklist, list)
 			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
 					 &entry->rule, sizeof(entry->rule));
@@ -250,8 +254,9 @@ int audit_receive_filter(int type, int p
 		audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
 		break;
 	case AUDIT_ADD:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
+		err = security_audit_listadd();
+		if (err)
+			return err;
 		if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
 			return -ENOMEM;
 		if (audit_copy_rule(&entry->rule, data)) {
@@ -267,6 +272,9 @@ int audit_receive_filter(int type, int p
 			err = audit_add_rule(entry, &audit_extlist);
 		break;
 	case AUDIT_DEL:
+		err = security_audit_listdel();
+		if (err)
+			return err;
 		flags =((struct audit_rule *)data)->flags;
 		if (!err && (flags & AUDIT_PER_TASK))
 			err = audit_del_rule(data, &audit_tsklist);
diff -pNru /home/hallyn/kernels/linux-2.6.8.1/security/dummy.c linux-2.6.8.1/security/dummy.c
--- /home/hallyn/kernels/linux-2.6.8.1/security/dummy.c	2004-08-14 05:54:51.000000000 -0500
+++ linux-2.6.8.1/security/dummy.c	2004-09-09 11:00:40.591867992 -0500
@@ -873,6 +873,34 @@ static int dummy_setprocattr(struct task
 	return -EINVAL;
 }
 
+static int dummy_audit_set(u32 mask)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+}
+
+static int dummy_audit_login(void)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+}
+
+static int dummy_audit_listfilter(void)
+{
+	return 0;
+}
+
+static int dummy_audit_listadd(void)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+}
+
+static int dummy_audit_listdel(void)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+}
 
 struct security_operations dummy_security_ops;
 
@@ -1005,6 +1033,11 @@ void security_fixup_ops (struct security
 	set_to_dummy_if_null(ops, d_instantiate);
  	set_to_dummy_if_null(ops, getprocattr);
  	set_to_dummy_if_null(ops, setprocattr);
+ 	set_to_dummy_if_null(ops, audit_set);
+	set_to_dummy_if_null(ops, audit_login);
+ 	set_to_dummy_if_null(ops, audit_listfilter);
+ 	set_to_dummy_if_null(ops, audit_listadd);
+ 	set_to_dummy_if_null(ops, audit_listdel);
 #ifdef CONFIG_SECURITY_NETWORK
 	set_to_dummy_if_null(ops, unix_stream_connect);
 	set_to_dummy_if_null(ops, unix_may_send);


----- End forwarded message -----




More information about the Linux-audit mailing list