deleting audit watch rules is not currently done under audit_filter_mutex.
It was done this way because we could not hold the mutex during inotify
manipulation.  Since we are using fsnotify we don't need to do the extra
get/put pair nor do we need the private list on which to store the parents
while they are about to be freed.

Signed-off-by: Eric Paris <[email protected]>
---

 kernel/audit.h       |    3 +--
 kernel/audit_watch.c |   27 +++------------------------
 kernel/auditfilter.c |    6 +-----
 3 files changed, 5 insertions(+), 31 deletions(-)

diff --git a/kernel/audit.h b/kernel/audit.h
index bf7118d..77a7e51 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -108,8 +108,7 @@ extern void audit_put_watch(struct audit_watch *watch);
 extern void audit_get_watch(struct audit_watch *watch);
 extern int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 
op);
 extern int audit_add_watch(struct audit_krule *krule, struct list_head **list);
-extern void audit_remove_watch_rule(struct audit_krule *krule, struct 
list_head *list);
-extern void audit_watch_inotify_unregister(struct list_head *in_list);
+extern void audit_remove_watch_rule(struct audit_krule *krule);
 extern char *audit_watch_path(struct audit_watch *watch);
 extern int audit_watch_compare(struct audit_watch *watch, unsigned long ino, 
dev_t dev);
 extern struct audit_entry *audit_dupe_rule(struct audit_krule *old);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index bd8df58..231f2a6 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -54,7 +54,6 @@ struct audit_watch {
 };
 
 struct audit_parent {
-       struct list_head        ilist;  /* tmp list used to free parents */
        struct list_head        watches; /* anchor for audit_watch->wlist */
        struct fsnotify_mark_entry mark; /* fsnotify mark on the inode */
 };
@@ -358,20 +357,6 @@ static void audit_remove_parent_watches(struct 
audit_parent *parent)
        fsnotify_destroy_mark_by_entry(&parent->mark);
 }
 
-/* Unregister inotify watches for parents on in_list.
- * Generates an FS_IGNORED event. */
-void audit_watch_inotify_unregister(struct list_head *in_list)
-{
-       struct audit_parent *p, *n;
-
-       list_for_each_entry_safe(p, n, in_list, ilist) {
-               list_del(&p->ilist);
-               fsnotify_destroy_mark_by_entry(&p->mark);
-               /* matches the get in audit_remove_watch_rule() */
-               audit_put_parent(p);
-       }
-}
-
 /* Get path information necessary for adding watches. */
 static int audit_get_path(const char *path, struct path *parent_path,
                          struct path *watch_path)
@@ -486,7 +471,7 @@ error:
 
 }
 
-void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)
+void audit_remove_watch_rule(struct audit_krule *krule)
 {
        struct audit_watch *watch = krule->watch;
        struct audit_parent *parent = watch->parent;
@@ -497,15 +482,9 @@ void audit_remove_watch_rule(struct audit_krule *krule, 
struct list_head *list)
                audit_remove_watch(watch);
 
                if (list_empty(&parent->watches)) {
-                       /* Put parent on the un-registration list.
-                        * Grab a reference before releasing
-                        * audit_filter_mutex, to be released in
-                        * audit_watch_inotify_unregister().
-                        * If filesystem is going away, just leave
-                        * the sucker alone, eviction will take
-                        * care of it. */
                        audit_get_parent(parent);
-                       list_add(&parent->ilist, list);
+                       fsnotify_destroy_mark_by_entry(&parent->mark);
+                       audit_put_parent(parent);
                }
        }
 }
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index f4dd2fc..f5e4cae 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -944,7 +944,6 @@ static inline int audit_del_rule(struct audit_entry *entry)
        struct audit_watch *watch = entry->rule.watch;
        struct audit_tree *tree = entry->rule.tree;
        struct list_head *list;
-       LIST_HEAD(inotify_unregister_list);
        int ret = 0;
 #ifdef CONFIG_AUDITSYSCALL
        int dont_count = 0;
@@ -964,7 +963,7 @@ static inline int audit_del_rule(struct audit_entry *entry)
        }
 
        if (e->rule.watch)
-               audit_remove_watch_rule(&e->rule, &inotify_unregister_list);
+               audit_remove_watch_rule(&e->rule);
 
        if (e->rule.tree)
                audit_remove_tree_rule(&e->rule);
@@ -982,9 +981,6 @@ static inline int audit_del_rule(struct audit_entry *entry)
 #endif
        mutex_unlock(&audit_filter_mutex);
 
-       if (!list_empty(&inotify_unregister_list))
-               audit_watch_inotify_unregister(&inotify_unregister_list);
-
 out:
        if (watch)
                audit_put_watch(watch); /* match initial get */

--
Linux-audit mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/linux-audit

Reply via email to