Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a05fb6cc authored by Eric Paris's avatar Eric Paris
Browse files

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: default avatarEric Paris <eparis@redhat.com>
parent e118e9c5
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);
+3 −24
Original line number Diff line number Diff line
@@ -55,7 +55,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 */
};
@@ -356,20 +355,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_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
{
@@ -502,7 +487,7 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)

}

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;
@@ -513,15 +498,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);
		}
	}
}
+1 −5
Original line number Diff line number Diff line
@@ -945,7 +945,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;
@@ -965,7 +964,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);
@@ -983,9 +982,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 */