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

Steve Grubb sgrubb at redhat.com
Thu Mar 30 13:57:43 UTC 2006


On Wednesday 29 March 2006 14:01, Stephen Smalley wrote:
> Not that I disagree with this change in approach, but I think that when
> it has come up in the past, there has been concern expressed about the
> fact that we could end up not being able to generate the context from
> the SID when the audit record is being emitted (due to OOM condition),

OK, attached below is a patch that I think addresses all your comments.
In testing this version, I noticed that I now have a 30% performace hit.
Somewhere between the two patches I lost 19% of the performance. 
I'm reviewing the differences to see what caused that.

There is one last loose end to this patch. I am adding a function,
selinux_ctxid_to_string. Is there an official SE Linux kernel API that
provides this? I'll fix Tim's patch to use the same API.

-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 18:08:04.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/selinux.h	2006-03-29 20:29:32.000000000 -0500
@@ -15,6 +15,7 @@
 
 struct selinux_audit_rule;
 struct audit_context;
+struct inode;
 
 #ifdef CONFIG_SECURITY_SELINUX
 
@@ -76,6 +77,28 @@ 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.
+ *     @gfp_mask: memory type mask
+ *
+ *     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, gfp_t gfp_mask);
+
+/**
+ *     selinux_get_inode_sid - get the inode's security context ID
+ *     @inode: inode structure to get the sid from.
+ *     @sid: security context ID returned.
+ *
+ *     Returns nothing
+ */
+void selinux_get_inode_sid(const struct inode *inode, u32 *sid);
+
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -107,6 +130,18 @@ static inline void selinux_task_ctxid(st
 	*ctxid = 0;
 }
 
+static inline void selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen, gfp_t gfp_mask)
+{
+       *ctx = NULL;
+       *ctxlen = 0;
+       return 0;
+}
+
+static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
+{
+	*sid = 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 18:08:07.000000000 -0500
+++ linux-2.6.16.x86_64/kernel/auditsc.c	2006-03-29 20:17:41.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,16 @@ 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;
+			int len;
+			if (selinux_ctxid_to_string(
+				context->names[i].osid, &ctx, &len, gfp_mask)){ 
+				audit_log_format(ab, " obj=%u",
+						context->names[i].osid);
+			} else 
+				audit_log_format(ab, " obj=%s", ctx);
+			kfree(ctx);
 		}
 
 		audit_log_end(ab);
@@ -983,37 +987,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())
+		selinux_get_inode_sid(inode, &context->names[idx].osid);
+	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 18:08:08.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/exports.c	2006-03-29 20:24:55.000000000 -0500
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/selinux.h>
+#include <linux/fs.h>
 
 #include "security.h"
 #include "objsec.h"
@@ -26,3 +27,27 @@ 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, gfp_t gfp_mask)
+{
+       if (ss_initialized)
+               return security_sid_to_context(ctxid, ctx, ctxlen);
+       else {
+               *ctx = NULL;
+               *ctxlen = 0;
+       }
+
+       return 0;
+}
+
+void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
+{
+	if (selinux_enabled) {
+		struct inode_security_struct *isec = inode->i_security;
+		*sid = isec->sid;
+	} else
+		*sid = 0;
+}
+




More information about the redhat-lspp mailing list