[redhat-lspp] [PATCH] change lspp inode auditing

Steve Grubb sgrubb at redhat.com
Wed Mar 29 18:28:42 UTC 2006


Hi,

This is a first draft patch to change the auditing of inodes for lspp.
Previously, we were gathering the context instead of the sid. Now in this patch, 
we gather just the sid and convert to context only if an audit event is being 
output. This patch makes no effort to account for policy_load. It also inserts
some functions that are likely going upstream via Se Linux kernel people. So,
that will need to be resolved before this patch is final. In any event its
good enough to test with. This patch brings the performance hit from
146% down to 11%. We need a similar patch for IPC syscall auditing.

-Steve


diff -urp linux-2.6.16.x86_64.orig/include/linux/selinux.h linux-2.6.16.x86_64/include/linux/selinux.h
--- linux-2.6.16.x86_64.orig/include/linux/selinux.h	2006-03-29 10:40:42.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/selinux.h	2006-03-29 10:27:06.000000000 -0500
@@ -13,6 +13,8 @@
 #ifndef _LINUX_SELINUX_H
 #define _LINUX_SELINUX_H
 
+#include <linux/fs.h>
+
 struct selinux_audit_rule;
 struct audit_context;
 
@@ -76,6 +78,26 @@ void selinux_audit_set_callback(int (*ca
  */
 void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
 
+/**
+ *     selinux_ctxid_to_string - map a security context ID to a string
+ *     @ctxid: security context ID to be converted.
+ *     @ctx: address of context string to be returned
+ *     @ctxlen: length of returned context string.
+ *
+ *     Returns 0 if successful, -errno if not.  On success, the context
+ *     string will be allocated internally, and the caller must call
+ *     kfree() on it after use.
+ */
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
+
+/**
+ *     selinux_get_inode_sid - get the inode's security context ID
+ *     @inode: inode structure to get the sid from.
+ *
+ *     Returns the sid if successful and 0 if unset
+ */
+u32 selinux_get_inode_sid(const struct inode *inode);
+
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -107,6 +129,18 @@ static inline void selinux_task_ctxid(st
 	*ctxid = 0;
 }
 
+static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
+{
+       *ctx = NULL;
+       *ctxlen = 0;
+       return 0;
+}
+
+static inline u32 selinux_get_inode_sid(const struct inode *inode)
+{
+	return 0;
+}
+
 #endif	/* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff -urp linux-2.6.16.x86_64.orig/kernel/auditsc.c linux-2.6.16.x86_64/kernel/auditsc.c
--- linux-2.6.16.x86_64.orig/kernel/auditsc.c	2006-03-29 10:40:48.000000000 -0500
+++ linux-2.6.16.x86_64/kernel/auditsc.c	2006-03-29 10:26:45.000000000 -0500
@@ -90,7 +90,7 @@ struct audit_names {
 	uid_t		uid;
 	gid_t		gid;
 	dev_t		rdev;
-	char		*ctx;
+	u32		osid;
 };
 
 struct audit_aux_data {
@@ -435,9 +435,6 @@ static inline void audit_free_names(stru
 #endif
 
 	for (i = 0; i < context->name_count; i++) {
-		char *p = context->names[i].ctx;
-		context->names[i].ctx = NULL;
-		kfree(p);
 		if (context->names[i].name)
 			__putname(context->names[i].name);
 	}
@@ -729,9 +726,24 @@ static void audit_log_exit(struct audit_
 					 context->names[i].gid, 
 					 MAJOR(context->names[i].rdev), 
 					 MINOR(context->names[i].rdev));
-		if (context->names[i].ctx) {
-			audit_log_format(ab, " obj=%s",
-					context->names[i].ctx);
+		if (context->names[i].osid != 0) {
+			char *ctx = NULL;
+			int len = 0;
+			if (selinux_ctxid_to_string(
+				context->names[i].osid, &ctx, &len) == 0) {
+				ctx = kmalloc(len, gfp_mask);
+				if (ctx) {
+					selinux_ctxid_to_string(
+		                                context->names[i].osid,
+						&ctx, &len);
+				}
+			}
+			if (ctx)
+				audit_log_format(ab, " obj=%s", ctx);
+			else
+				audit_log_format(ab, " obj=%u",
+						context->names[i].osid);
+			kfree(ctx);
 		}
 
 		audit_log_end(ab);
@@ -983,37 +995,10 @@ void audit_putname(const char *name)
 void audit_inode_context(int idx, const struct inode *inode)
 {
 	struct audit_context *context = current->audit_context;
-	const char *suffix = security_inode_xattr_getsuffix();
-	char *ctx = NULL;
-	int len = 0;
-
-	if (!suffix)
-		goto ret;
-
-	len = security_inode_getsecurity(inode, suffix, NULL, 0, 0);
-	if (len == -EOPNOTSUPP)
-		goto ret;
-	if (len < 0) 
-		goto error_path;
-
-	ctx = kmalloc(len, GFP_KERNEL);
-	if (!ctx) 
-		goto error_path;
-
-	len = security_inode_getsecurity(inode, suffix, ctx, len, 0);
-	if (len < 0)
-		goto error_path;
-
-	kfree(context->names[idx].ctx);
-	context->names[idx].ctx = ctx;
-	goto ret;
-
-error_path:
-	if (ctx)
-		kfree(ctx);
-	audit_panic("error in audit_inode_context");
-ret:
-	return;
+	if (security_inode_xattr_getsuffix())
+		context->names[idx].osid = selinux_get_inode_sid(inode);
+	else
+		context->names[idx].osid = 0;
 }
 
 
diff -urp linux-2.6.16.x86_64.orig/security/selinux/exports.c linux-2.6.16.x86_64/security/selinux/exports.c
--- linux-2.6.16.x86_64.orig/security/selinux/exports.c	2006-03-29 10:40:51.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/exports.c	2006-03-29 10:26:45.000000000 -0500
@@ -26,3 +26,24 @@ void selinux_task_ctxid(struct task_stru
 	else
 		*ctxid = 0;
 }
+
+extern int ss_initialized;
+
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
+{
+       if (ss_initialized)
+               return security_sid_to_context(ctxid, ctx, ctxlen);
+       else {
+               *ctx = NULL;
+               *ctxlen = 0;
+       }
+
+       return 0;
+}
+
+u32 selinux_get_inode_sid(const struct inode *inode)
+{
+	struct inode_security_struct *isec = inode->i_security;
+	return isec->sid;
+}
+




More information about the redhat-lspp mailing list