[PATCH] change lspp inode auditing

Steve Grubb sgrubb at redhat.com
Thu Mar 30 18:47:30 UTC 2006


On Thursday 30 March 2006 10:48, Steve Grubb wrote:
> > Not much value in displaying the SID, although we do it elsewhere as
> > well (e.g. in the AVC) as a fallback - mapping it will then require a
> > dump of kernel memory at that time.  Likely have to call audit_panic in
> > this scenario to meet the criteria, but the admin can always set
> > audit_panic to not actually panic the machine.
>
> I'll patch it to call audit_panic, but that is not the solution. For
> example, suppose the syscall was to rename, sendfile, unlink, or link to a
> file...even though we panic they were able to do the action. If it was
> rename a file, they can now access the file when it comes back up and not
> be audited. I think that the correct course of action is to log the number
> and figure out how to close the loop on the mapping the sid to context
> post-mortem.

OK, below is a patch that I think addresses all issues pointed out. I've
benchmarked it and we are at 23% performance hit. That's much better
than before.

Signed-off-by: Steve Grubb <sgrubb at redhat.com>


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-30 12:01:15.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/selinux.h	2006-03-30 12:04:42.000000000 -0500
@@ -15,6 +15,7 @@
 
 struct selinux_audit_rule;
 struct audit_context;
+struct inode;
 
 #ifdef CONFIG_SECURITY_SELINUX
 
@@ -76,6 +77,27 @@ 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.
+ *     @sid: pointer to security context ID to be filled in.
+ *
+ *     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 +128,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 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-30 12:01:21.000000000 -0500
+++ linux-2.6.16.x86_64/kernel/auditsc.c	2006-03-30 12:06:01.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);
 	}
@@ -700,6 +697,7 @@ static void audit_log_exit(struct audit_
 		}
 	}
 	for (i = 0; i < context->name_count; i++) {
+		int call_panic = 0;
 		unsigned long ino  = context->names[i].ino;
 		unsigned long pino = context->names[i].pino;
 
@@ -729,12 +727,22 @@ 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;
+			if (selinux_ctxid_to_string(
+				context->names[i].osid, &ctx, &len)) { 
+				audit_log_format(ab, " obj=%u",
+						context->names[i].osid);
+				call_panic = 1;
+			} else 
+				audit_log_format(ab, " obj=%s", ctx);
+			kfree(ctx);
 		}
 
 		audit_log_end(ab);
+		if (call_panic)
+			audit_panic("error converting sid to string");
 	}
 }
 
@@ -983,37 +991,8 @@ 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;
+	selinux_get_inode_sid(inode, &context->names[idx].osid);
 }
 
 
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-30 12:01:23.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/exports.c	2006-03-30 12:05:30.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,26 @@ void selinux_task_ctxid(struct task_stru
 	else
 		*ctxid = 0;
 }
+
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
+{
+	if (selinux_enabled)
+		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;
+		return;
+	}
+	*sid = 0;
+}
+




More information about the Linux-audit mailing list