audit: do not get and put just to free a watch
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 <eparis@redhat.com>
This commit is contained in:
Родитель
e118e9c563
Коммит
a05fb6cc57
|
@ -108,8 +108,7 @@ extern void audit_put_watch(struct audit_watch *watch);
|
||||||
extern void audit_get_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_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 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_remove_watch_rule(struct audit_krule *krule);
|
||||||
extern void audit_watch_inotify_unregister(struct list_head *in_list);
|
|
||||||
extern char *audit_watch_path(struct audit_watch *watch);
|
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 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);
|
extern struct audit_entry *audit_dupe_rule(struct audit_krule *old);
|
||||||
|
|
|
@ -55,7 +55,6 @@ struct audit_watch {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct audit_parent {
|
struct audit_parent {
|
||||||
struct list_head ilist; /* tmp list used to free parents */
|
|
||||||
struct list_head watches; /* anchor for audit_watch->wlist */
|
struct list_head watches; /* anchor for audit_watch->wlist */
|
||||||
struct fsnotify_mark_entry mark; /* fsnotify mark on the inode */
|
struct fsnotify_mark_entry mark; /* fsnotify mark on the inode */
|
||||||
};
|
};
|
||||||
|
@ -356,20 +355,6 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
|
||||||
fsnotify_destroy_mark_by_entry(&parent->mark);
|
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. */
|
/* Get path information necessary for adding watches. */
|
||||||
static int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
|
static int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
|
||||||
{
|
{
|
||||||
|
@ -502,7 +487,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_watch *watch = krule->watch;
|
||||||
struct audit_parent *parent = watch->parent;
|
struct audit_parent *parent = watch->parent;
|
||||||
|
@ -513,15 +498,9 @@ void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)
|
||||||
audit_remove_watch(watch);
|
audit_remove_watch(watch);
|
||||||
|
|
||||||
if (list_empty(&parent->watches)) {
|
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);
|
audit_get_parent(parent);
|
||||||
list_add(&parent->ilist, list);
|
fsnotify_destroy_mark_by_entry(&parent->mark);
|
||||||
|
audit_put_parent(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -945,7 +945,6 @@ static inline int audit_del_rule(struct audit_entry *entry)
|
||||||
struct audit_watch *watch = entry->rule.watch;
|
struct audit_watch *watch = entry->rule.watch;
|
||||||
struct audit_tree *tree = entry->rule.tree;
|
struct audit_tree *tree = entry->rule.tree;
|
||||||
struct list_head *list;
|
struct list_head *list;
|
||||||
LIST_HEAD(inotify_unregister_list);
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
#ifdef CONFIG_AUDITSYSCALL
|
#ifdef CONFIG_AUDITSYSCALL
|
||||||
int dont_count = 0;
|
int dont_count = 0;
|
||||||
|
@ -965,7 +964,7 @@ static inline int audit_del_rule(struct audit_entry *entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->rule.watch)
|
if (e->rule.watch)
|
||||||
audit_remove_watch_rule(&e->rule, &inotify_unregister_list);
|
audit_remove_watch_rule(&e->rule);
|
||||||
|
|
||||||
if (e->rule.tree)
|
if (e->rule.tree)
|
||||||
audit_remove_tree_rule(&e->rule);
|
audit_remove_tree_rule(&e->rule);
|
||||||
|
@ -983,9 +982,6 @@ static inline int audit_del_rule(struct audit_entry *entry)
|
||||||
#endif
|
#endif
|
||||||
mutex_unlock(&audit_filter_mutex);
|
mutex_unlock(&audit_filter_mutex);
|
||||||
|
|
||||||
if (!list_empty(&inotify_unregister_list))
|
|
||||||
audit_watch_inotify_unregister(&inotify_unregister_list);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (watch)
|
if (watch)
|
||||||
audit_put_watch(watch); /* match initial get */
|
audit_put_watch(watch); /* match initial get */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче