Lines Matching +full:in +full:- +full:tree
1 // SPDX-License-Identifier: GPL-2.0
54 * audit_tree_group->mark_mutex. Thus as long as we hold
55 * audit_tree_group->mark_mutex and check that the mark is alive by
61 * the same tree.
63 * time and used in AUDIT_TREE rule matching.
68 * tree.chunks anchors chunk.owners[].list hash_lock
69 * tree.rules anchors rule.rlist audit_filter_mutex
70 * chunk.trees anchors tree.same_root hash_lock
74 * tree is refcounted; one reference for "some rules on rules_list refer to
86 * revert - several operations have very unpleasant cleanup logics and
95 struct audit_tree *tree;
97 tree = kmalloc(struct_size(tree, pathname, strlen(s) + 1), GFP_KERNEL);
98 if (tree) {
99 refcount_set(&tree->count, 1);
100 tree->goner = 0;
101 INIT_LIST_HEAD(&tree->chunks);
102 INIT_LIST_HEAD(&tree->rules);
103 INIT_LIST_HEAD(&tree->list);
104 INIT_LIST_HEAD(&tree->same_root);
105 tree->root = NULL;
106 strcpy(tree->pathname, s);
108 return tree;
111 static inline void get_tree(struct audit_tree *tree)
113 refcount_inc(&tree->count);
116 static inline void put_tree(struct audit_tree *tree)
118 if (refcount_dec_and_test(&tree->count))
119 kfree_rcu(tree, head);
122 /* to avoid bringing the entire thing in audit.h */
123 const char *audit_tree_path(struct audit_tree *tree)
125 return tree->pathname;
132 for (i = 0; i < chunk->count; i++) {
133 if (chunk->owners[i].owner)
134 put_tree(chunk->owners[i].owner);
141 if (atomic_long_dec_and_test(&chunk->refs))
158 call_rcu(&chunk->head, __put_chunk);
168 return audit_mark(mark)->chunk;
183 fsnotify_init_mark(&amark->mark, audit_tree_group);
184 amark->mark.mask = FS_IN_IGNORED;
185 return &amark->mark;
197 INIT_LIST_HEAD(&chunk->hash);
198 INIT_LIST_HEAD(&chunk->trees);
199 chunk->count = count;
200 atomic_long_set(&chunk->refs, 1);
202 INIT_LIST_HEAD(&chunk->owners[i].list);
203 chunk->owners[i].index = i;
212 /* Function to return search key in our hash from inode. */
215 /* Use address pointed to by connector->obj as the key */
216 return (unsigned long)&inode->i_fsnotify_marks;
225 /* hash_lock & mark->group->mark_mutex is held by caller */
231 * Make sure chunk is fully initialized before making it visible in the
232 * hash. Pairs with a data dependency barrier in READ_ONCE() in
236 WARN_ON_ONCE(!chunk->key);
237 list = chunk_hash(chunk->key);
238 list_add_rcu(&chunk->hash, list);
250 * We use a data dependency barrier in READ_ONCE() to make sure
253 if (READ_ONCE(p->key) == key) {
254 atomic_long_inc(&p->refs);
261 bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
264 for (n = 0; n < chunk->count; n++)
265 if (chunk->owners[n].owner == tree)
274 int index = p->index & ~(1U<<31);
275 p -= index;
286 audit_mark(mark)->chunk = chunk;
288 chunk->mark = mark;
290 old->mark = NULL;
298 new->key = old->key;
299 list_splice_init(&old->trees, &new->trees);
300 list_for_each_entry(owner, &new->trees, same_root)
301 owner->root = new;
302 for (i = j = 0; j < old->count; i++, j++) {
303 if (!old->owners[j].owner) {
304 i--;
307 owner = old->owners[j].owner;
308 new->owners[i].owner = owner;
309 new->owners[i].index = old->owners[j].index - j + i;
313 list_replace_init(&old->owners[j].list, &new->owners[i].list);
315 replace_mark_chunk(old->mark, new);
317 * Make sure chunk is fully initialized before making it visible in the
318 * hash. Pairs with a data dependency barrier in READ_ONCE() in
322 list_replace_rcu(&old->hash, &new->hash);
327 struct audit_tree *owner = p->owner;
329 if (owner->root == chunk) {
330 list_del_init(&owner->same_root);
331 owner->root = NULL;
333 list_del_init(&p->list);
334 p->owner = NULL;
343 for (i = 0; i < chunk->count; i++)
344 if (chunk->owners[i].owner)
359 if (!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) ||
366 list_del_init(&chunk->trees);
367 list_del_rcu(&chunk->hash);
396 /* Call with group->mark_mutex held, releases it */
397 static int create_chunk(struct inode *inode, struct audit_tree *tree)
404 return -ENOMEM;
411 return -ENOMEM;
418 return -ENOSPC;
422 if (tree->goner) {
432 chunk->owners[0].index = (1U << 31);
433 chunk->owners[0].owner = tree;
434 get_tree(tree);
435 list_add(&chunk->owners[0].list, &tree->chunks);
436 if (!tree->root) {
437 tree->root = chunk;
438 list_add(&tree->same_root, &chunk->trees);
440 chunk->key = inode_to_key(inode);
450 * we get notification through ->freeing_mark callback and cleanup
457 /* the first tagged inode becomes root of tree */
458 static int tag_chunk(struct inode *inode, struct audit_tree *tree)
468 return create_chunk(inode, tree);
478 for (n = 0; n < old->count; n++) {
479 if (old->owners[n].owner == tree) {
488 chunk = alloc_chunk(old->count + 1);
492 return -ENOMEM;
496 if (tree->goner) {
503 p = &chunk->owners[chunk->count - 1];
504 p->index = (chunk->count - 1) | (1U<<31);
505 p->owner = tree;
506 get_tree(tree);
507 list_add(&p->list, &tree->chunks);
508 if (!tree->root) {
509 tree->root = chunk;
510 list_add(&tree->same_root, &chunk->trees);
536 audit_log_untrustedstring(ab, rule->tree->pathname);
537 audit_log_key(ab, rule->filterkey);
538 audit_log_format(ab, " list=%d res=1", rule->listnr);
542 static void kill_rules(struct audit_context *context, struct audit_tree *tree)
547 list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
550 list_del_init(&rule->rlist);
551 if (rule->tree) {
552 /* not a half-baked one */
554 if (entry->rule.exe)
555 audit_remove_mark(entry->rule.exe);
556 rule->tree = NULL;
557 list_del_rcu(&entry->list);
558 list_del(&entry->rule.list);
559 call_rcu(&entry->rcu, audit_free_rule_rcu);
565 * Remove tree from chunks. If 'tagged' is set, remove tree only from tagged
572 while (!list_empty(&victim->chunks)) {
577 p = list_first_entry(&victim->chunks, struct audit_node, list);
579 if (tagged && !(p->index & (1U<<31)))
582 mark = chunk->mark;
607 /* trim the uncommitted chunks from tree */
609 static void trim_marked(struct audit_tree *tree)
613 if (tree->goner) {
618 for (p = tree->chunks.next; p != &tree->chunks; p = q) {
620 q = p->next;
621 if (node->index & (1U<<31)) {
623 list_add(p, &tree->chunks);
628 prune_tree_chunks(tree, true);
631 if (!tree->root && !tree->goner) {
632 tree->goner = 1;
635 kill_rules(audit_context(), tree);
636 list_del_init(&tree->list);
638 prune_one(tree);
649 struct audit_tree *tree;
650 tree = rule->tree;
651 if (tree) {
653 list_del_init(&rule->rlist);
654 if (list_empty(&tree->rules) && !tree->goner) {
655 tree->root = NULL;
656 list_del_init(&tree->same_root);
657 tree->goner = 1;
658 list_move(&tree->list, &prune_list);
659 rule->tree = NULL;
664 rule->tree = NULL;
673 return inode_to_key(d_backing_inode(mnt->mnt_root)) ==
684 struct audit_tree *tree;
690 tree = container_of(cursor.next, struct audit_tree, list);
691 get_tree(tree);
692 list_move(&cursor, &tree->list);
695 err = kern_path(tree->pathname, 0, &path);
705 list_for_each_entry(node, &tree->chunks, list) {
708 node->index |= 1U<<31;
710 (void *)(chunk->key),
712 node->index &= ~(1U<<31);
715 trim_marked(tree);
718 put_tree(tree);
729 (rule->listnr != AUDIT_FILTER_EXIT &&
730 rule->listnr != AUDIT_FILTER_URING_EXIT) ||
732 rule->inode_f || rule->watch || rule->tree)
733 return -EINVAL;
734 rule->tree = alloc_tree(pathname);
735 if (!rule->tree)
736 return -ENOMEM;
740 void audit_put_tree(struct audit_tree *tree)
742 put_tree(tree);
747 return tag_chunk(d_backing_inode(mnt->mnt_root), arg);
770 list_del_init(&victim->list);
794 return -ENOMEM;
802 struct audit_tree *seed = rule->tree, *tree;
807 rule->tree = NULL;
808 list_for_each_entry(tree, &tree_list, list) {
809 if (!strcmp(seed->pathname, tree->pathname)) {
811 rule->tree = tree;
812 list_add(&rule->rlist, &tree->rules);
816 tree = seed;
817 list_add(&tree->list, &tree_list);
818 list_add(&rule->rlist, &tree->rules);
819 /* do not set rule->tree yet */
828 err = kern_path(tree->pathname, 0, &path);
838 get_tree(tree);
839 err = iterate_mounts(tag_mount, tree, mnt);
845 list_for_each_entry(node, &tree->chunks, list)
846 node->index &= ~(1U<<31);
849 trim_marked(tree);
854 if (list_empty(&rule->rlist)) {
855 put_tree(tree);
856 return -ENOENT;
858 rule->tree = tree;
859 put_tree(tree);
864 list_del_init(&tree->list);
865 list_del_init(&tree->rules);
866 put_tree(tree);
897 struct audit_tree *tree;
900 tree = container_of(cursor.next, struct audit_tree, list);
901 get_tree(tree);
902 list_move(&cursor, &tree->list);
905 err = kern_path(tree->pathname, 0, &path2);
912 put_tree(tree);
917 failed = iterate_mounts(tag_mount, tree, tagged);
919 put_tree(tree);
926 if (!tree->goner) {
927 list_move(&tree->list, &tree_list);
930 put_tree(tree);
934 struct audit_tree *tree;
936 tree = container_of(barrier.prev, struct audit_tree, list);
937 get_tree(tree);
938 list_move(&tree->list, &barrier);
944 list_for_each_entry(node, &tree->chunks, list)
945 node->index &= ~(1U<<31);
948 trim_marked(tree);
951 put_tree(tree);
974 struct list_head *list = &context->killed_trees;
982 victim = list_entry(list->next, struct audit_tree, list);
984 list_del_init(&victim->list);
1010 while (!list_empty(&chunk->trees)) {
1011 owner = list_entry(chunk->trees.next,
1013 owner->goner = 1;
1014 owner->root = NULL;
1015 list_del_init(&owner->same_root);
1019 list_move(&owner->list, &prune_list);
1022 list_move(&owner->list, postponed);
1026 list_del_rcu(&chunk->hash);
1027 for (n = 0; n < chunk->count; n++)
1028 list_del_init(&chunk->owners[n].list);
1047 fsnotify_group_lock(mark->group);
1052 fsnotify_group_unlock(mark->group);
1062 BUG_ON(refcount_read(&mark->refcnt) < 1);