[PATCH] get dev value for inode audit records

Chris Wright chrisw at osdl.org
Thu Feb 24 19:17:09 UTC 2005


* Stephen Smalley (sds at tycho.nsa.gov) wrote:
> On Tue, 2005-02-22 at 09:54 -0800, Chris Wright wrote:
> > The dev value is actually rdev.  So it's not bogus if you're accessing,
> > for example, /dev/hda1.  Reasonable question whether that's both
> > intentional and sufficient.  Given namespace possibilities, I assumed
> > that dev/ino pair was dumped to uniquely identify the object.
> 
> Yes, this looks like a bug to me in the audit code, particularly as the
> existing filter code lets you filter based on rdev and ino (whereas I'd
> expect you would want to filter based on a specific object identified by
> (dev,ino) pair).  Should path_lookup() be passing nd->dentry->d_inode-
> >i_sb->s_dev to audit_inode() instead?

That's what I was thinking, Erich said he'd give the patch a test.  I
kept rdev and added dev.  But, from the perspective of the converstaion
we had in the other thread (re: supplemental groups), shouldn't the
security attributes of the object be dumped as well?  Here's a patch to
try Erich, but I think I'll spin up another one to dump uid/gid too.

thanks,
-chris

===== kernel/auditsc.c 1.6 vs edited =====
--- 1.6/kernel/auditsc.c	2005-01-30 22:33:47 -08:00
+++ edited/kernel/auditsc.c	2005-02-24 11:10:04 -08:00
@@ -89,6 +89,7 @@ enum audit_state {
 struct audit_names {
 	const char	*name;
 	unsigned long	ino;
+	dev_t		dev;
 	dev_t		rdev;
 };
 
@@ -338,7 +339,7 @@ static int audit_filter_rules(struct tas
 		case AUDIT_DEVMAJOR:
 			if (ctx) {
 				for (j = 0; j < ctx->name_count; j++) {
-					if (MAJOR(ctx->names[j].rdev)==value) {
+					if (MAJOR(ctx->names[j].dev)==value) {
 						++result;
 						break;
 					}
@@ -348,7 +349,7 @@ static int audit_filter_rules(struct tas
 		case AUDIT_DEVMINOR:
 			if (ctx) {
 				for (j = 0; j < ctx->name_count; j++) {
-					if (MINOR(ctx->names[j].rdev)==value) {
+					if (MINOR(ctx->names[j].dev)==value) {
 						++result;
 						break;
 					}
@@ -620,8 +621,12 @@ static void audit_log_exit(struct audit_
 					 context->names[i].ino);
 		/* FIXME: should use format_dev_t, but ab structure is
 		 * opaque. */
-		if (context->names[i].rdev != -1)
+		if (context->names[i].dev != -1)
 			audit_log_format(ab, " dev=%02x:%02x",
+					 MAJOR(context->names[i].dev),
+					 MINOR(context->names[i].dev));
+		if (context->names[i].rdev != -1)
+			audit_log_format(ab, " rdev=%02x:%02x",
 					 MAJOR(context->names[i].rdev),
 					 MINOR(context->names[i].rdev));
 		audit_log_end(ab);
@@ -812,6 +817,7 @@ void audit_getname(const char *name)
 	BUG_ON(context->name_count >= AUDIT_NAMES);
 	context->names[context->name_count].name = name;
 	context->names[context->name_count].ino  = (unsigned long)-1;
+	context->names[context->name_count].dev  = -1;
 	context->names[context->name_count].rdev = -1;
 	++context->name_count;
 }
@@ -859,7 +865,7 @@ EXPORT_SYMBOL(audit_putname);
 
 /* Store the inode and device from a lookup.  Called from
  * fs/namei.c:path_lookup(). */
-void audit_inode(const char *name, unsigned long ino, dev_t rdev)
+void audit_inode(const char *name, unsigned long ino, dev_t dev, dev_t rdev)
 {
 	int idx;
 	struct audit_context *context = current->audit_context;
@@ -886,6 +892,7 @@ void audit_inode(const char *name, unsig
 #endif
 	}
 	context->names[idx].ino  = ino;
+	context->names[idx].dev	 = dev;
 	context->names[idx].rdev = rdev;
 }
 
===== fs/namei.c 1.118 vs edited =====
--- 1.118/fs/namei.c	2005-01-20 21:00:21 -08:00
+++ edited/fs/namei.c	2005-02-24 11:02:46 -08:00
@@ -983,6 +983,7 @@ int fastcall path_lookup(const char *nam
 		     && nd && nd->dentry && nd->dentry->d_inode))
 		audit_inode(name,
 			    nd->dentry->d_inode->i_ino,
+			    nd->dentry->d_inode->i_sb->s_dev,
 			    nd->dentry->d_inode->i_rdev);
 	return retval;
 }
===== include/linux/audit.h 1.2 vs edited =====
--- 1.2/include/linux/audit.h	2005-01-30 22:33:47 -08:00
+++ edited/include/linux/audit.h	2005-02-24 10:58:24 -08:00
@@ -141,7 +141,7 @@ extern void audit_syscall_entry(struct t
 extern void audit_syscall_exit(struct task_struct *task, int return_code);
 extern void audit_getname(const char *name);
 extern void audit_putname(const char *name);
-extern void audit_inode(const char *name, unsigned long ino, dev_t rdev);
+extern void audit_inode(const char *name, unsigned long ino, dev_t dev, dev_t rdev);
 
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
@@ -157,7 +157,7 @@ extern uid_t audit_get_loginuid(struct a
 #define audit_syscall_exit(t,r) do { ; } while (0)
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
-#define audit_inode(n,i,d) do { ; } while (0)
+#define audit_inode(n,i,d, r) do { ; } while (0)
 #define audit_get_loginuid(c) ({ -1; })
 #endif
 




More information about the Linux-audit mailing list