Lines Matching +full:rules +full:- +full:anchors

1 // SPDX-License-Identifier: GPL-2.0
18 struct list_head rules; member
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
59 * Rules have pointer to struct audit_tree.
60 * Rules have struct list_head rlist forming a list of rules over
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
99 refcount_set(&tree->count, 1); in alloc_tree()
100 tree->goner = 0; in alloc_tree()
101 INIT_LIST_HEAD(&tree->chunks); in alloc_tree()
102 INIT_LIST_HEAD(&tree->rules); in alloc_tree()
103 INIT_LIST_HEAD(&tree->list); in alloc_tree()
104 INIT_LIST_HEAD(&tree->same_root); in alloc_tree()
105 tree->root = NULL; in alloc_tree()
106 strcpy(tree->pathname, s); in alloc_tree()
113 refcount_inc(&tree->count); in get_tree()
118 if (refcount_dec_and_test(&tree->count)) in put_tree()
125 return tree->pathname; in audit_tree_path()
132 for (i = 0; i < chunk->count; i++) { in free_chunk()
133 if (chunk->owners[i].owner) in free_chunk()
134 put_tree(chunk->owners[i].owner); in free_chunk()
141 if (atomic_long_dec_and_test(&chunk->refs)) in audit_put_chunk()
158 call_rcu(&chunk->head, __put_chunk); in audit_mark_put_chunk()
168 return audit_mark(mark)->chunk; in mark_chunk()
183 fsnotify_init_mark(&amark->mark, audit_tree_group); in alloc_mark()
184 amark->mark.mask = FS_IN_IGNORED; in alloc_mark()
185 return &amark->mark; in alloc_mark()
197 INIT_LIST_HEAD(&chunk->hash); in alloc_chunk()
198 INIT_LIST_HEAD(&chunk->trees); in alloc_chunk()
199 chunk->count = count; in alloc_chunk()
200 atomic_long_set(&chunk->refs, 1); in alloc_chunk()
202 INIT_LIST_HEAD(&chunk->owners[i].list); in alloc_chunk()
203 chunk->owners[i].index = i; in alloc_chunk()
215 /* Use address pointed to by connector->obj as the key */ in inode_to_key()
216 return (unsigned long)&inode->i_fsnotify_marks; in inode_to_key()
225 /* hash_lock & mark->group->mark_mutex is held by caller */
236 WARN_ON_ONCE(!chunk->key); in insert_hash()
237 list = chunk_hash(chunk->key); in insert_hash()
238 list_add_rcu(&chunk->hash, list); in insert_hash()
253 if (READ_ONCE(p->key) == key) { in audit_tree_lookup()
254 atomic_long_inc(&p->refs); in audit_tree_lookup()
264 for (n = 0; n < chunk->count; n++) in audit_tree_match()
265 if (chunk->owners[n].owner == tree) in audit_tree_match()
274 int index = p->index & ~(1U<<31); in find_chunk()
275 p -= index; in find_chunk()
286 audit_mark(mark)->chunk = chunk; in replace_mark_chunk()
288 chunk->mark = mark; in replace_mark_chunk()
290 old->mark = NULL; in replace_mark_chunk()
298 new->key = old->key; in replace_chunk()
299 list_splice_init(&old->trees, &new->trees); in replace_chunk()
300 list_for_each_entry(owner, &new->trees, same_root) in replace_chunk()
301 owner->root = new; in replace_chunk()
302 for (i = j = 0; j < old->count; i++, j++) { in replace_chunk()
303 if (!old->owners[j].owner) { in replace_chunk()
304 i--; in replace_chunk()
307 owner = old->owners[j].owner; in replace_chunk()
308 new->owners[i].owner = owner; in replace_chunk()
309 new->owners[i].index = old->owners[j].index - j + i; in replace_chunk()
313 list_replace_init(&old->owners[j].list, &new->owners[i].list); in replace_chunk()
315 replace_mark_chunk(old->mark, new); in replace_chunk()
322 list_replace_rcu(&old->hash, &new->hash); in replace_chunk()
327 struct audit_tree *owner = p->owner; in remove_chunk_node()
329 if (owner->root == chunk) { in remove_chunk_node()
330 list_del_init(&owner->same_root); in remove_chunk_node()
331 owner->root = NULL; in remove_chunk_node()
333 list_del_init(&p->list); in remove_chunk_node()
334 p->owner = NULL; in remove_chunk_node()
343 for (i = 0; i < chunk->count; i++) in chunk_count_trees()
344 if (chunk->owners[i].owner) in chunk_count_trees()
359 if (!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) || in untag_chunk()
366 list_del_init(&chunk->trees); in untag_chunk()
367 list_del_rcu(&chunk->hash); in untag_chunk()
396 /* Call with group->mark_mutex held, releases it */
404 return -ENOMEM; in create_chunk()
411 return -ENOMEM; in create_chunk()
418 return -ENOSPC; in create_chunk()
422 if (tree->goner) { in create_chunk()
432 chunk->owners[0].index = (1U << 31); in create_chunk()
433 chunk->owners[0].owner = tree; in create_chunk()
435 list_add(&chunk->owners[0].list, &tree->chunks); in create_chunk()
436 if (!tree->root) { in create_chunk()
437 tree->root = chunk; in create_chunk()
438 list_add(&tree->same_root, &chunk->trees); in create_chunk()
440 chunk->key = inode_to_key(inode); in create_chunk()
450 * we get notification through ->freeing_mark callback and cleanup in create_chunk()
478 for (n = 0; n < old->count; n++) { in tag_chunk()
479 if (old->owners[n].owner == tree) { in tag_chunk()
488 chunk = alloc_chunk(old->count + 1); in tag_chunk()
492 return -ENOMEM; in tag_chunk()
496 if (tree->goner) { in tag_chunk()
503 p = &chunk->owners[chunk->count - 1]; in tag_chunk()
504 p->index = (chunk->count - 1) | (1U<<31); in tag_chunk()
505 p->owner = tree; in tag_chunk()
507 list_add(&p->list, &tree->chunks); in tag_chunk()
508 if (!tree->root) { in tag_chunk()
509 tree->root = chunk; in tag_chunk()
510 list_add(&tree->same_root, &chunk->trees); in tag_chunk()
536 audit_log_untrustedstring(ab, rule->tree->pathname); in audit_tree_log_remove_rule()
537 audit_log_key(ab, rule->filterkey); in audit_tree_log_remove_rule()
538 audit_log_format(ab, " list=%d res=1", rule->listnr); in audit_tree_log_remove_rule()
547 list_for_each_entry_safe(rule, next, &tree->rules, rlist) { in kill_rules()
550 list_del_init(&rule->rlist); in kill_rules()
551 if (rule->tree) { in kill_rules()
552 /* not a half-baked one */ in kill_rules()
554 if (entry->rule.exe) in kill_rules()
555 audit_remove_mark(entry->rule.exe); in kill_rules()
556 rule->tree = NULL; in kill_rules()
557 list_del_rcu(&entry->list); in kill_rules()
558 list_del(&entry->rule.list); in kill_rules()
559 call_rcu(&entry->rcu, audit_free_rule_rcu); in kill_rules()
572 while (!list_empty(&victim->chunks)) { in prune_tree_chunks()
577 p = list_first_entry(&victim->chunks, struct audit_node, list); in prune_tree_chunks()
579 if (tagged && !(p->index & (1U<<31))) in prune_tree_chunks()
582 mark = chunk->mark; in prune_tree_chunks()
613 if (tree->goner) { in trim_marked()
618 for (p = tree->chunks.next; p != &tree->chunks; p = q) { in trim_marked()
620 q = p->next; in trim_marked()
621 if (node->index & (1U<<31)) { in trim_marked()
623 list_add(p, &tree->chunks); in trim_marked()
631 if (!tree->root && !tree->goner) { in trim_marked()
632 tree->goner = 1; in trim_marked()
636 list_del_init(&tree->list); in trim_marked()
650 tree = rule->tree; in audit_remove_tree_rule()
653 list_del_init(&rule->rlist); in audit_remove_tree_rule()
654 if (list_empty(&tree->rules) && !tree->goner) { in audit_remove_tree_rule()
655 tree->root = NULL; in audit_remove_tree_rule()
656 list_del_init(&tree->same_root); in audit_remove_tree_rule()
657 tree->goner = 1; in audit_remove_tree_rule()
658 list_move(&tree->list, &prune_list); in audit_remove_tree_rule()
659 rule->tree = NULL; in audit_remove_tree_rule()
664 rule->tree = NULL; in audit_remove_tree_rule()
673 return inode_to_key(d_backing_inode(mnt->mnt_root)) == in compare_root()
692 list_move(&cursor, &tree->list); in audit_trim_trees()
695 err = kern_path(tree->pathname, 0, &path); in audit_trim_trees()
705 list_for_each_entry(node, &tree->chunks, list) { in audit_trim_trees()
708 node->index |= 1U<<31; in audit_trim_trees()
710 (void *)(chunk->key), in audit_trim_trees()
712 node->index &= ~(1U<<31); in audit_trim_trees()
729 (rule->listnr != AUDIT_FILTER_EXIT && in audit_make_tree()
730 rule->listnr != AUDIT_FILTER_URING_EXIT) || in audit_make_tree()
732 rule->inode_f || rule->watch || rule->tree) in audit_make_tree()
733 return -EINVAL; in audit_make_tree()
734 rule->tree = alloc_tree(pathname); in audit_make_tree()
735 if (!rule->tree) in audit_make_tree()
736 return -ENOMEM; in audit_make_tree()
747 return tag_chunk(d_backing_inode(mnt->mnt_root), arg); in tag_mount()
770 list_del_init(&victim->list); in prune_tree_thread()
794 return -ENOMEM; in audit_launch_prune()
802 struct audit_tree *seed = rule->tree, *tree; in audit_add_tree_rule()
807 rule->tree = NULL; in audit_add_tree_rule()
809 if (!strcmp(seed->pathname, tree->pathname)) { in audit_add_tree_rule()
811 rule->tree = tree; in audit_add_tree_rule()
812 list_add(&rule->rlist, &tree->rules); in audit_add_tree_rule()
817 list_add(&tree->list, &tree_list); in audit_add_tree_rule()
818 list_add(&rule->rlist, &tree->rules); in audit_add_tree_rule()
819 /* do not set rule->tree yet */ in audit_add_tree_rule()
828 err = kern_path(tree->pathname, 0, &path); in audit_add_tree_rule()
845 list_for_each_entry(node, &tree->chunks, list) in audit_add_tree_rule()
846 node->index &= ~(1U<<31); in audit_add_tree_rule()
854 if (list_empty(&rule->rlist)) { in audit_add_tree_rule()
856 return -ENOENT; in audit_add_tree_rule()
858 rule->tree = tree; in audit_add_tree_rule()
864 list_del_init(&tree->list); in audit_add_tree_rule()
865 list_del_init(&tree->rules); in audit_add_tree_rule()
902 list_move(&cursor, &tree->list); in audit_tag_tree()
905 err = kern_path(tree->pathname, 0, &path2); in audit_tag_tree()
926 if (!tree->goner) { in audit_tag_tree()
927 list_move(&tree->list, &tree_list); in audit_tag_tree()
938 list_move(&tree->list, &barrier); in audit_tag_tree()
944 list_for_each_entry(node, &tree->chunks, list) in audit_tag_tree()
945 node->index &= ~(1U<<31); in audit_tag_tree()
974 struct list_head *list = &context->killed_trees; in audit_kill_trees()
982 victim = list_entry(list->next, struct audit_tree, list); in audit_kill_trees()
984 list_del_init(&victim->list); in audit_kill_trees()
1010 while (!list_empty(&chunk->trees)) { in evict_chunk()
1011 owner = list_entry(chunk->trees.next, in evict_chunk()
1013 owner->goner = 1; in evict_chunk()
1014 owner->root = NULL; in evict_chunk()
1015 list_del_init(&owner->same_root); in evict_chunk()
1019 list_move(&owner->list, &prune_list); in evict_chunk()
1022 list_move(&owner->list, postponed); in evict_chunk()
1026 list_del_rcu(&chunk->hash); in evict_chunk()
1027 for (n = 0; n < chunk->count; n++) in evict_chunk()
1028 list_del_init(&chunk->owners[n].list); in evict_chunk()
1047 fsnotify_group_lock(mark->group); in audit_tree_freeing_mark()
1052 fsnotify_group_unlock(mark->group); in audit_tree_freeing_mark()
1062 BUG_ON(refcount_read(&mark->refcnt) < 1); in audit_tree_freeing_mark()