[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH] fix missed create event for directory audit



When an object is created via a symlink into an audited directory, audit misses
the event due to not having collected the inode data for the directory.  Modify
__audit_inode_child() to copy the parent inode data if a parent wasn't found in
audit_names[].

Signed-off-by: Amy Griffis <amy griffis hp com>
---
 fs/namei.c               |    2 +-
 include/linux/audit.h    |    8 ++++----
 include/linux/fsnotify.h |    6 +++---
 kernel/auditsc.c         |   16 +++++++++++++---
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 8904b4f..f9ffe6d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1357,7 +1357,7 @@ static int may_delete(struct inode *dir,
 		return -ENOENT;
 
 	BUG_ON(victim->d_parent->d_inode != dir);
-	audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino);
+	audit_inode_child(victim->d_name.name, victim->d_inode, dir);
 
 	error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
 	if (error)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index c63f204..2803163 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -327,7 +327,7 @@ extern void __audit_getname(const char *
 extern void audit_putname(const char *name);
 extern void __audit_inode(const char *name, const struct inode *inode);
 extern void __audit_inode_child(const char *dname, const struct inode *inode,
-				unsigned long pino);
+				const struct inode *parent);
 extern void __audit_inode_update(const struct inode *inode);
 static inline void audit_getname(const char *name)
 {
@@ -339,10 +339,10 @@ static inline void audit_inode(const cha
 		__audit_inode(name, inode);
 }
 static inline void audit_inode_child(const char *dname, 
-				     const struct inode *inode, 
-				     unsigned long pino) {
+				     const struct inode *inode,
+				     const struct inode *parent) {
 	if (unlikely(current->audit_context))
-		__audit_inode_child(dname, inode, pino);
+		__audit_inode_child(dname, inode, parent);
 }
 static inline void audit_inode_update(const struct inode *inode) {
 	if (unlikely(current->audit_context))
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index cc5dec7..d4f219f 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -67,7 +67,7 @@ static inline void fsnotify_move(struct 
 	if (source) {
 		inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL);
 	}
-	audit_inode_child(new_name, source, new_dir->i_ino);
+	audit_inode_child(new_name, source, new_dir);
 }
 
 /*
@@ -98,7 +98,7 @@ static inline void fsnotify_create(struc
 	inode_dir_notify(inode, DN_CREATE);
 	inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name,
 				  dentry->d_inode);
-	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
+	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
 }
 
 /*
@@ -109,7 +109,7 @@ static inline void fsnotify_mkdir(struct
 	inode_dir_notify(inode, DN_CREATE);
 	inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, 
 				  dentry->d_name.name, dentry->d_inode);
-	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino);
+	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
 }
 
 /*
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 0bc584d..d440fe4 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1252,7 +1252,7 @@ #endif
  * audit_inode_child - collect inode info for created/removed objects
  * @dname: inode's dentry name
  * @inode: inode being audited
- * @pino: inode number of dentry parent
+ * @parent: inode of dentry parent
  *
  * For syscalls that create or remove filesystem objects, audit_inode
  * can only collect information for the filesystem object's parent.
@@ -1263,7 +1263,7 @@ #endif
  * unsuccessful attempts.
  */
 void __audit_inode_child(const char *dname, const struct inode *inode,
-			 unsigned long pino)
+			 const struct inode *parent)
 {
 	int idx;
 	struct audit_context *context = current->audit_context;
@@ -1277,7 +1277,7 @@ void __audit_inode_child(const char *dna
 	if (!dname)
 		goto update_context;
 	for (idx = 0; idx < context->name_count; idx++)
-		if (context->names[idx].ino == pino) {
+		if (context->names[idx].ino == parent->i_ino) {
 			const char *name = context->names[idx].name;
 
 			if (!name)
@@ -1305,6 +1305,16 @@ #endif
 		context->names[idx].ino = (unsigned long)-1;
 	else
 		audit_copy_inode(&context->names[idx], inode);
+
+	/* A parent was not found in audit_names, so copy the inode data for the
+	 * provided parent. */
+	if (!found_name) {
+		idx = context->name_count++;
+#if AUDIT_DEBUG
+		context->ino_count++;
+#endif
+		audit_copy_inode(&context->names[idx], parent);
+	}
 }
 
 /**
-- 
1.4.0


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]