[PATCH 13/14] audit: continue fleshing out audit by exe

Richard Guy Briggs rgb at redhat.com
Wed Jun 18 03:09:48 UTC 2014


---
 include/linux/audit.h   |    1 +
 kernel/audit.h          |    1 +
 kernel/audit_fsnotify.c |   15 +++++++++++++++
 kernel/auditfilter.c    |   21 ++++++++++++++++++++-
 4 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index f2a8044..0bb9ea6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -43,6 +43,7 @@ struct mq_attr;
 struct mqstat;
 struct audit_watch;
 struct audit_tree;
+struct audit_fsnotify_mark;
 struct sk_buff;
 
 struct audit_krule {
diff --git a/kernel/audit.h b/kernel/audit.h
index 7bf3138..2093c5e 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -285,6 +285,7 @@ extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev
 
 struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pathname, int len);
 char *audit_mark_path(struct audit_fsnotify_mark *mark);
+int audit_add_mark_rule(struct audit_krule *krule, struct list_head **list);
 void audit_remove_mark(struct audit_fsnotify_mark *audit_mark);
 int audit_mark_compare(struct audit_fsnotify_mark *mark, unsigned long ino, dev_t dev);
 
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index efefa16..cc4175a 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -161,6 +161,21 @@ static void audit_mark_log_rule_change(struct audit_fsnotify_mark *audit_mark, c
 	audit_log_end(ab);
 }
 
+int audit_add_mark_rule(struct audit_krule *krule, struct list_head **list)
+{
+	struct audit_fsnotify_mark *audit_mark;
+	int h, ret = 0;
+
+	if (krule->exe)
+		audit_mark = krule->exe;
+	else
+		return -EINVAL;  //XXX
+
+	h = audit_hash_ino((u32)audit_mark->ino);
+	*list = &audit_inode_hash[h];
+	return ret;
+}
+
 static int audit_update_mark(struct audit_fsnotify_mark *audit_mark,
 			     struct inode *inode)
 {
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index f40c13b..7b6e892 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -34,6 +34,7 @@
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include "audit.h"
+#include <linux/fsnotify_backend.h>
 
 /*
  * Locking model:
@@ -79,6 +80,8 @@ static inline void audit_free_rule(struct audit_entry *e)
 	/* some rules don't have associated watches */
 	if (erule->watch)
 		audit_put_watch(erule->watch);
+	if (erule->exe)
+		fsnotify_put_mark(erule->exe->mark);
 	if (erule->fields)
 		for (i = 0; i < erule->field_count; i++) {
 			struct audit_field *f = &erule->fields[i];
@@ -566,6 +569,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
 				err = PTR_ERR(audit_mark);
 				goto exit_free;
 			}
+			fsnotify_get_mark(audit_mark->mark);
 			entry->rule.exe = audit_mark;
 			break;
 		}
@@ -582,6 +586,8 @@ exit_free:
 		audit_put_watch(entry->rule.watch); /* matches initial get */
 	if (entry->rule.tree)
 		audit_put_tree(entry->rule.tree); /* that's the temporary one */
+	if (entry->rule.exe)
+		fsnotify_put_mark(entry->rule.exe->mark); /* matches initial get */
 	audit_free_rule(entry);
 	return ERR_PTR(err);
 }
@@ -866,7 +872,7 @@ static struct audit_entry *audit_find_rule(struct audit_entry *entry,
 	if (entry->rule.inode_f) {
 		h = audit_hash_ino(entry->rule.inode_f->val);
 		*p = list = &audit_inode_hash[h];
-	} else if (entry->rule.watch) {
+	} else if (entry->rule.watch || entry->rule.exe) {
 		/* we don't know the inode number, so must walk entire hash */
 		for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
 			list = &audit_inode_hash[h];
@@ -900,6 +906,7 @@ static inline int audit_add_rule(struct audit_entry *entry)
 	struct audit_entry *e;
 	struct audit_watch *watch = entry->rule.watch;
 	struct audit_tree *tree = entry->rule.tree;
+	struct audit_fsnotify_mark *exe = entry->rule.exe;
 	struct list_head *list;
 	int err;
 #ifdef CONFIG_AUDITSYSCALL
@@ -943,6 +950,13 @@ static inline int audit_add_rule(struct audit_entry *entry)
 			goto error;
 		}
 	}
+	if (exe) {
+		err = audit_add_mark_rule(&entry->rule, &list);
+		if (err) {
+			mutex_unlock(&audit_filter_mutex);
+			goto error;
+		}
+	}
 
 	entry->rule.prio = ~0ULL;
 	if (entry->rule.listnr == AUDIT_FILTER_EXIT) {
@@ -976,6 +990,8 @@ static inline int audit_add_rule(struct audit_entry *entry)
 error:
 	if (watch)
 		audit_put_watch(watch); /* tmp watch, matches initial get */
+	if (exe)
+		fsnotify_put_mark(exe->mark); /* tmp mark, matches initial get */
 	return err;
 }
 
@@ -985,6 +1001,7 @@ int audit_del_rule(struct audit_entry *entry)
 	struct audit_entry  *e;
 	struct audit_watch *watch = entry->rule.watch;
 	struct audit_tree *tree = entry->rule.tree;
+	struct audit_fsnotify_mark *exe = entry->rule.exe;
 	struct list_head *list;
 	int ret = 0;
 #ifdef CONFIG_AUDITSYSCALL
@@ -1031,6 +1048,8 @@ out:
 		audit_put_watch(watch); /* match initial get */
 	if (tree)
 		audit_put_tree(tree);	/* that's the temporary one */
+	if (exe)
+		fsnotify_put_mark(exe->mark);	/* match initial get */
 
 	return ret;
 }
-- 
1.7.1




More information about the Linux-audit mailing list