Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : #include "audit.h"
3 : : #include <linux/fsnotify_backend.h>
4 : : #include <linux/namei.h>
5 : : #include <linux/mount.h>
6 : : #include <linux/kthread.h>
7 : : #include <linux/refcount.h>
8 : : #include <linux/slab.h>
9 : :
10 : : struct audit_tree;
11 : : struct audit_chunk;
12 : :
13 : : struct audit_tree {
14 : : refcount_t count;
15 : : int goner;
16 : : struct audit_chunk *root;
17 : : struct list_head chunks;
18 : : struct list_head rules;
19 : : struct list_head list;
20 : : struct list_head same_root;
21 : : struct rcu_head head;
22 : : char pathname[];
23 : : };
24 : :
25 : : struct audit_chunk {
26 : : struct list_head hash;
27 : : unsigned long key;
28 : : struct fsnotify_mark *mark;
29 : : struct list_head trees; /* with root here */
30 : : int count;
31 : : atomic_long_t refs;
32 : : struct rcu_head head;
33 : : struct node {
34 : : struct list_head list;
35 : : struct audit_tree *owner;
36 : : unsigned index; /* index; upper bit indicates 'will prune' */
37 : : } owners[];
38 : : };
39 : :
40 : : struct audit_tree_mark {
41 : : struct fsnotify_mark mark;
42 : : struct audit_chunk *chunk;
43 : : };
44 : :
45 : : static LIST_HEAD(tree_list);
46 : : static LIST_HEAD(prune_list);
47 : : static struct task_struct *prune_thread;
48 : :
49 : : /*
50 : : * One struct chunk is attached to each inode of interest through
51 : : * audit_tree_mark (fsnotify mark). We replace struct chunk on tagging /
52 : : * untagging, the mark is stable as long as there is chunk attached. The
53 : : * association between mark and chunk is protected by hash_lock and
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
56 : : * FSNOTIFY_MARK_FLAG_ATTACHED flag check, we are sure the mark points to
57 : : * the current chunk.
58 : : *
59 : : * Rules have pointer to struct audit_tree.
60 : : * Rules have struct list_head rlist forming a list of rules over
61 : : * the same tree.
62 : : * References to struct chunk are collected at audit_inode{,_child}()
63 : : * time and used in AUDIT_TREE rule matching.
64 : : * These references are dropped at the same time we are calling
65 : : * audit_free_names(), etc.
66 : : *
67 : : * Cyclic lists galore:
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
71 : : * chunk.hash is a hash with middle bits of watch.inode as
72 : : * a hash function. RCU, hash_lock
73 : : *
74 : : * tree is refcounted; one reference for "some rules on rules_list refer to
75 : : * it", one for each chunk with pointer to it.
76 : : *
77 : : * chunk is refcounted by embedded .refs. Mark associated with the chunk holds
78 : : * one chunk reference. This reference is dropped either when a mark is going
79 : : * to be freed (corresponding inode goes away) or when chunk attached to the
80 : : * mark gets replaced. This reference must be dropped using
81 : : * audit_mark_put_chunk() to make sure the reference is dropped only after RCU
82 : : * grace period as it protects RCU readers of the hash table.
83 : : *
84 : : * node.index allows to get from node.list to containing chunk.
85 : : * MSB of that sucker is stolen to mark taggings that we might have to
86 : : * revert - several operations have very unpleasant cleanup logics and
87 : : * that makes a difference. Some.
88 : : */
89 : :
90 : : static struct fsnotify_group *audit_tree_group;
91 : : static struct kmem_cache *audit_tree_mark_cachep __read_mostly;
92 : :
93 : 0 : static struct audit_tree *alloc_tree(const char *s)
94 : : {
95 : 0 : struct audit_tree *tree;
96 : :
97 [ # # ]: 0 : tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
98 [ # # ]: 0 : if (tree) {
99 : 0 : refcount_set(&tree->count, 1);
100 : 0 : tree->goner = 0;
101 : 0 : INIT_LIST_HEAD(&tree->chunks);
102 : 0 : INIT_LIST_HEAD(&tree->rules);
103 : 0 : INIT_LIST_HEAD(&tree->list);
104 : 0 : INIT_LIST_HEAD(&tree->same_root);
105 : 0 : tree->root = NULL;
106 : 0 : strcpy(tree->pathname, s);
107 : : }
108 : 0 : return tree;
109 : : }
110 : :
111 : 0 : static inline void get_tree(struct audit_tree *tree)
112 : : {
113 : 0 : refcount_inc(&tree->count);
114 : : }
115 : :
116 : 0 : static inline void put_tree(struct audit_tree *tree)
117 : : {
118 [ # # ]: 0 : if (refcount_dec_and_test(&tree->count))
119 [ # # ]: 0 : kfree_rcu(tree, head);
120 : 0 : }
121 : :
122 : : /* to avoid bringing the entire thing in audit.h */
123 : 0 : const char *audit_tree_path(struct audit_tree *tree)
124 : : {
125 : 0 : return tree->pathname;
126 : : }
127 : :
128 : 0 : static void free_chunk(struct audit_chunk *chunk)
129 : : {
130 : 0 : int i;
131 : :
132 [ # # ]: 0 : for (i = 0; i < chunk->count; i++) {
133 [ # # ]: 0 : if (chunk->owners[i].owner)
134 : 0 : put_tree(chunk->owners[i].owner);
135 : : }
136 : 0 : kfree(chunk);
137 : 0 : }
138 : :
139 : 0 : void audit_put_chunk(struct audit_chunk *chunk)
140 : : {
141 [ # # ]: 0 : if (atomic_long_dec_and_test(&chunk->refs))
142 : 0 : free_chunk(chunk);
143 : 0 : }
144 : :
145 : 0 : static void __put_chunk(struct rcu_head *rcu)
146 : : {
147 : 0 : struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
148 : 0 : audit_put_chunk(chunk);
149 : 0 : }
150 : :
151 : : /*
152 : : * Drop reference to the chunk that was held by the mark. This is the reference
153 : : * that gets dropped after we've removed the chunk from the hash table and we
154 : : * use it to make sure chunk cannot be freed before RCU grace period expires.
155 : : */
156 : 0 : static void audit_mark_put_chunk(struct audit_chunk *chunk)
157 : : {
158 : 0 : call_rcu(&chunk->head, __put_chunk);
159 : 0 : }
160 : :
161 : 0 : static inline struct audit_tree_mark *audit_mark(struct fsnotify_mark *mark)
162 : : {
163 : 0 : return container_of(mark, struct audit_tree_mark, mark);
164 : : }
165 : :
166 : 0 : static struct audit_chunk *mark_chunk(struct fsnotify_mark *mark)
167 : : {
168 : 0 : return audit_mark(mark)->chunk;
169 : : }
170 : :
171 : 0 : static void audit_tree_destroy_watch(struct fsnotify_mark *mark)
172 : : {
173 : 0 : kmem_cache_free(audit_tree_mark_cachep, audit_mark(mark));
174 : 0 : }
175 : :
176 : 0 : static struct fsnotify_mark *alloc_mark(void)
177 : : {
178 : 0 : struct audit_tree_mark *amark;
179 : :
180 : 0 : amark = kmem_cache_zalloc(audit_tree_mark_cachep, GFP_KERNEL);
181 [ # # ]: 0 : if (!amark)
182 : : return NULL;
183 : 0 : fsnotify_init_mark(&amark->mark, audit_tree_group);
184 : 0 : amark->mark.mask = FS_IN_IGNORED;
185 : 0 : return &amark->mark;
186 : : }
187 : :
188 : 0 : static struct audit_chunk *alloc_chunk(int count)
189 : : {
190 : 0 : struct audit_chunk *chunk;
191 : 0 : size_t size;
192 : 0 : int i;
193 : :
194 : 0 : size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node);
195 : 0 : chunk = kzalloc(size, GFP_KERNEL);
196 [ # # ]: 0 : if (!chunk)
197 : : return NULL;
198 : :
199 : 0 : INIT_LIST_HEAD(&chunk->hash);
200 : 0 : INIT_LIST_HEAD(&chunk->trees);
201 : 0 : chunk->count = count;
202 : 0 : atomic_long_set(&chunk->refs, 1);
203 [ # # ]: 0 : for (i = 0; i < count; i++) {
204 : 0 : INIT_LIST_HEAD(&chunk->owners[i].list);
205 : 0 : chunk->owners[i].index = i;
206 : : }
207 : : return chunk;
208 : : }
209 : :
210 : : enum {HASH_SIZE = 128};
211 : : static struct list_head chunk_hash_heads[HASH_SIZE];
212 : : static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock);
213 : :
214 : : /* Function to return search key in our hash from inode. */
215 : 0 : static unsigned long inode_to_key(const struct inode *inode)
216 : : {
217 : : /* Use address pointed to by connector->obj as the key */
218 : 0 : return (unsigned long)&inode->i_fsnotify_marks;
219 : : }
220 : :
221 : 0 : static inline struct list_head *chunk_hash(unsigned long key)
222 : : {
223 : 0 : unsigned long n = key / L1_CACHE_BYTES;
224 : 0 : return chunk_hash_heads + n % HASH_SIZE;
225 : : }
226 : :
227 : : /* hash_lock & mark->group->mark_mutex is held by caller */
228 : 0 : static void insert_hash(struct audit_chunk *chunk)
229 : : {
230 : 0 : struct list_head *list;
231 : :
232 : : /*
233 : : * Make sure chunk is fully initialized before making it visible in the
234 : : * hash. Pairs with a data dependency barrier in READ_ONCE() in
235 : : * audit_tree_lookup().
236 : : */
237 : 0 : smp_wmb();
238 [ # # ]: 0 : WARN_ON_ONCE(!chunk->key);
239 : 0 : list = chunk_hash(chunk->key);
240 : 0 : list_add_rcu(&chunk->hash, list);
241 : 0 : }
242 : :
243 : : /* called under rcu_read_lock */
244 : 0 : struct audit_chunk *audit_tree_lookup(const struct inode *inode)
245 : : {
246 : 0 : unsigned long key = inode_to_key(inode);
247 : 0 : struct list_head *list = chunk_hash(key);
248 : 0 : struct audit_chunk *p;
249 : :
250 [ # # ]: 0 : list_for_each_entry_rcu(p, list, hash) {
251 : : /*
252 : : * We use a data dependency barrier in READ_ONCE() to make sure
253 : : * the chunk we see is fully initialized.
254 : : */
255 [ # # ]: 0 : if (READ_ONCE(p->key) == key) {
256 : 0 : atomic_long_inc(&p->refs);
257 : 0 : return p;
258 : : }
259 : : }
260 : : return NULL;
261 : : }
262 : :
263 : 0 : bool audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
264 : : {
265 : 0 : int n;
266 [ # # ]: 0 : for (n = 0; n < chunk->count; n++)
267 [ # # ]: 0 : if (chunk->owners[n].owner == tree)
268 : : return true;
269 : : return false;
270 : : }
271 : :
272 : : /* tagging and untagging inodes with trees */
273 : :
274 : 0 : static struct audit_chunk *find_chunk(struct node *p)
275 : : {
276 : 0 : int index = p->index & ~(1U<<31);
277 : 0 : p -= index;
278 : 0 : return container_of(p, struct audit_chunk, owners[0]);
279 : : }
280 : :
281 : 0 : static void replace_mark_chunk(struct fsnotify_mark *mark,
282 : : struct audit_chunk *chunk)
283 : : {
284 : 0 : struct audit_chunk *old;
285 : :
286 [ # # ]: 0 : assert_spin_locked(&hash_lock);
287 : 0 : old = mark_chunk(mark);
288 : 0 : audit_mark(mark)->chunk = chunk;
289 [ # # ]: 0 : if (chunk)
290 : 0 : chunk->mark = mark;
291 [ # # ]: 0 : if (old)
292 : 0 : old->mark = NULL;
293 : 0 : }
294 : :
295 : 0 : static void replace_chunk(struct audit_chunk *new, struct audit_chunk *old)
296 : : {
297 : 0 : struct audit_tree *owner;
298 : 0 : int i, j;
299 : :
300 : 0 : new->key = old->key;
301 [ # # ]: 0 : list_splice_init(&old->trees, &new->trees);
302 [ # # ]: 0 : list_for_each_entry(owner, &new->trees, same_root)
303 : 0 : owner->root = new;
304 [ # # ]: 0 : for (i = j = 0; j < old->count; i++, j++) {
305 [ # # ]: 0 : if (!old->owners[j].owner) {
306 : 0 : i--;
307 : 0 : continue;
308 : : }
309 : 0 : owner = old->owners[j].owner;
310 : 0 : new->owners[i].owner = owner;
311 : 0 : new->owners[i].index = old->owners[j].index - j + i;
312 : 0 : if (!owner) /* result of earlier fallback */
313 : : continue;
314 : 0 : get_tree(owner);
315 : 0 : list_replace_init(&old->owners[j].list, &new->owners[i].list);
316 : : }
317 : 0 : replace_mark_chunk(old->mark, new);
318 : : /*
319 : : * Make sure chunk is fully initialized before making it visible in the
320 : : * hash. Pairs with a data dependency barrier in READ_ONCE() in
321 : : * audit_tree_lookup().
322 : : */
323 : 0 : smp_wmb();
324 : 0 : list_replace_rcu(&old->hash, &new->hash);
325 : 0 : }
326 : :
327 : 0 : static void remove_chunk_node(struct audit_chunk *chunk, struct node *p)
328 : : {
329 : 0 : struct audit_tree *owner = p->owner;
330 : :
331 [ # # ]: 0 : if (owner->root == chunk) {
332 : 0 : list_del_init(&owner->same_root);
333 : 0 : owner->root = NULL;
334 : : }
335 : 0 : list_del_init(&p->list);
336 : 0 : p->owner = NULL;
337 : 0 : put_tree(owner);
338 : 0 : }
339 : :
340 : : static int chunk_count_trees(struct audit_chunk *chunk)
341 : : {
342 : : int i;
343 : : int ret = 0;
344 : :
345 [ # # ]: 0 : for (i = 0; i < chunk->count; i++)
346 [ # # ]: 0 : if (chunk->owners[i].owner)
347 : 0 : ret++;
348 : 0 : return ret;
349 : : }
350 : :
351 : 0 : static void untag_chunk(struct audit_chunk *chunk, struct fsnotify_mark *mark)
352 : : {
353 : 0 : struct audit_chunk *new;
354 : 0 : int size;
355 : :
356 : 0 : mutex_lock(&audit_tree_group->mark_mutex);
357 : : /*
358 : : * mark_mutex stabilizes chunk attached to the mark so we can check
359 : : * whether it didn't change while we've dropped hash_lock.
360 : : */
361 [ # # # # ]: 0 : if (!(mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) ||
362 : : mark_chunk(mark) != chunk)
363 : 0 : goto out_mutex;
364 : :
365 : : size = chunk_count_trees(chunk);
366 [ # # ]: 0 : if (!size) {
367 : 0 : spin_lock(&hash_lock);
368 : 0 : list_del_init(&chunk->trees);
369 : 0 : list_del_rcu(&chunk->hash);
370 : 0 : replace_mark_chunk(mark, NULL);
371 : 0 : spin_unlock(&hash_lock);
372 : 0 : fsnotify_detach_mark(mark);
373 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
374 : 0 : audit_mark_put_chunk(chunk);
375 : 0 : fsnotify_free_mark(mark);
376 : 0 : return;
377 : : }
378 : :
379 : 0 : new = alloc_chunk(size);
380 [ # # ]: 0 : if (!new)
381 : 0 : goto out_mutex;
382 : :
383 : 0 : spin_lock(&hash_lock);
384 : : /*
385 : : * This has to go last when updating chunk as once replace_chunk() is
386 : : * called, new RCU readers can see the new chunk.
387 : : */
388 : 0 : replace_chunk(new, chunk);
389 : 0 : spin_unlock(&hash_lock);
390 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
391 : 0 : audit_mark_put_chunk(chunk);
392 : : return;
393 : :
394 : 0 : out_mutex:
395 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
396 : : }
397 : :
398 : : /* Call with group->mark_mutex held, releases it */
399 : 0 : static int create_chunk(struct inode *inode, struct audit_tree *tree)
400 : : {
401 : 0 : struct fsnotify_mark *mark;
402 : 0 : struct audit_chunk *chunk = alloc_chunk(1);
403 : :
404 [ # # ]: 0 : if (!chunk) {
405 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
406 : 0 : return -ENOMEM;
407 : : }
408 : :
409 : 0 : mark = alloc_mark();
410 [ # # ]: 0 : if (!mark) {
411 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
412 : 0 : kfree(chunk);
413 : 0 : return -ENOMEM;
414 : : }
415 : :
416 [ # # ]: 0 : if (fsnotify_add_inode_mark_locked(mark, inode, 0)) {
417 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
418 : 0 : fsnotify_put_mark(mark);
419 : 0 : kfree(chunk);
420 : 0 : return -ENOSPC;
421 : : }
422 : :
423 : 0 : spin_lock(&hash_lock);
424 [ # # ]: 0 : if (tree->goner) {
425 : 0 : spin_unlock(&hash_lock);
426 : 0 : fsnotify_detach_mark(mark);
427 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
428 : 0 : fsnotify_free_mark(mark);
429 : 0 : fsnotify_put_mark(mark);
430 : 0 : kfree(chunk);
431 : 0 : return 0;
432 : : }
433 : 0 : replace_mark_chunk(mark, chunk);
434 : 0 : chunk->owners[0].index = (1U << 31);
435 : 0 : chunk->owners[0].owner = tree;
436 : 0 : get_tree(tree);
437 [ # # ]: 0 : list_add(&chunk->owners[0].list, &tree->chunks);
438 [ # # ]: 0 : if (!tree->root) {
439 : 0 : tree->root = chunk;
440 : 0 : list_add(&tree->same_root, &chunk->trees);
441 : : }
442 : 0 : chunk->key = inode_to_key(inode);
443 : : /*
444 : : * Inserting into the hash table has to go last as once we do that RCU
445 : : * readers can see the chunk.
446 : : */
447 : 0 : insert_hash(chunk);
448 : 0 : spin_unlock(&hash_lock);
449 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
450 : : /*
451 : : * Drop our initial reference. When mark we point to is getting freed,
452 : : * we get notification through ->freeing_mark callback and cleanup
453 : : * chunk pointing to this mark.
454 : : */
455 : 0 : fsnotify_put_mark(mark);
456 : 0 : return 0;
457 : : }
458 : :
459 : : /* the first tagged inode becomes root of tree */
460 : 0 : static int tag_chunk(struct inode *inode, struct audit_tree *tree)
461 : : {
462 : 0 : struct fsnotify_mark *mark;
463 : 0 : struct audit_chunk *chunk, *old;
464 : 0 : struct node *p;
465 : 0 : int n;
466 : :
467 : 0 : mutex_lock(&audit_tree_group->mark_mutex);
468 : 0 : mark = fsnotify_find_mark(&inode->i_fsnotify_marks, audit_tree_group);
469 [ # # ]: 0 : if (!mark)
470 : 0 : return create_chunk(inode, tree);
471 : :
472 : : /*
473 : : * Found mark is guaranteed to be attached and mark_mutex protects mark
474 : : * from getting detached and thus it makes sure there is chunk attached
475 : : * to the mark.
476 : : */
477 : : /* are we already there? */
478 : 0 : spin_lock(&hash_lock);
479 : 0 : old = mark_chunk(mark);
480 [ # # ]: 0 : for (n = 0; n < old->count; n++) {
481 [ # # ]: 0 : if (old->owners[n].owner == tree) {
482 : 0 : spin_unlock(&hash_lock);
483 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
484 : 0 : fsnotify_put_mark(mark);
485 : 0 : return 0;
486 : : }
487 : : }
488 : 0 : spin_unlock(&hash_lock);
489 : :
490 : 0 : chunk = alloc_chunk(old->count + 1);
491 [ # # ]: 0 : if (!chunk) {
492 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
493 : 0 : fsnotify_put_mark(mark);
494 : 0 : return -ENOMEM;
495 : : }
496 : :
497 : 0 : spin_lock(&hash_lock);
498 [ # # ]: 0 : if (tree->goner) {
499 : 0 : spin_unlock(&hash_lock);
500 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
501 : 0 : fsnotify_put_mark(mark);
502 : 0 : kfree(chunk);
503 : 0 : return 0;
504 : : }
505 : 0 : p = &chunk->owners[chunk->count - 1];
506 : 0 : p->index = (chunk->count - 1) | (1U<<31);
507 : 0 : p->owner = tree;
508 : 0 : get_tree(tree);
509 [ # # ]: 0 : list_add(&p->list, &tree->chunks);
510 [ # # ]: 0 : if (!tree->root) {
511 : 0 : tree->root = chunk;
512 : 0 : list_add(&tree->same_root, &chunk->trees);
513 : : }
514 : : /*
515 : : * This has to go last when updating chunk as once replace_chunk() is
516 : : * called, new RCU readers can see the new chunk.
517 : : */
518 : 0 : replace_chunk(chunk, old);
519 : 0 : spin_unlock(&hash_lock);
520 : 0 : mutex_unlock(&audit_tree_group->mark_mutex);
521 : 0 : fsnotify_put_mark(mark); /* pair to fsnotify_find_mark */
522 : 0 : audit_mark_put_chunk(old);
523 : :
524 : 0 : return 0;
525 : : }
526 : :
527 : 0 : static void audit_tree_log_remove_rule(struct audit_context *context,
528 : : struct audit_krule *rule)
529 : : {
530 : 0 : struct audit_buffer *ab;
531 : :
532 [ # # ]: 0 : if (!audit_enabled)
533 : : return;
534 : 0 : ab = audit_log_start(context, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
535 [ # # ]: 0 : if (unlikely(!ab))
536 : : return;
537 : 0 : audit_log_format(ab, "op=remove_rule dir=");
538 : 0 : audit_log_untrustedstring(ab, rule->tree->pathname);
539 : 0 : audit_log_key(ab, rule->filterkey);
540 : 0 : audit_log_format(ab, " list=%d res=1", rule->listnr);
541 : 0 : audit_log_end(ab);
542 : : }
543 : :
544 : 0 : static void kill_rules(struct audit_context *context, struct audit_tree *tree)
545 : : {
546 : 0 : struct audit_krule *rule, *next;
547 : 0 : struct audit_entry *entry;
548 : :
549 [ # # ]: 0 : list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
550 : 0 : entry = container_of(rule, struct audit_entry, rule);
551 : :
552 [ # # ]: 0 : list_del_init(&rule->rlist);
553 [ # # ]: 0 : if (rule->tree) {
554 : : /* not a half-baked one */
555 : 0 : audit_tree_log_remove_rule(context, rule);
556 [ # # ]: 0 : if (entry->rule.exe)
557 : 0 : audit_remove_mark(entry->rule.exe);
558 : 0 : rule->tree = NULL;
559 : 0 : list_del_rcu(&entry->list);
560 : 0 : list_del(&entry->rule.list);
561 : 0 : call_rcu(&entry->rcu, audit_free_rule_rcu);
562 : : }
563 : : }
564 : 0 : }
565 : :
566 : : /*
567 : : * Remove tree from chunks. If 'tagged' is set, remove tree only from tagged
568 : : * chunks. The function expects tagged chunks are all at the beginning of the
569 : : * chunks list.
570 : : */
571 : 0 : static void prune_tree_chunks(struct audit_tree *victim, bool tagged)
572 : : {
573 : 0 : spin_lock(&hash_lock);
574 [ # # ]: 0 : while (!list_empty(&victim->chunks)) {
575 : 0 : struct node *p;
576 : 0 : struct audit_chunk *chunk;
577 : 0 : struct fsnotify_mark *mark;
578 : :
579 : 0 : p = list_first_entry(&victim->chunks, struct node, list);
580 : : /* have we run out of marked? */
581 [ # # # # ]: 0 : if (tagged && !(p->index & (1U<<31)))
582 : : break;
583 : 0 : chunk = find_chunk(p);
584 : 0 : mark = chunk->mark;
585 : 0 : remove_chunk_node(chunk, p);
586 : : /* Racing with audit_tree_freeing_mark()? */
587 [ # # ]: 0 : if (!mark)
588 : 0 : continue;
589 : 0 : fsnotify_get_mark(mark);
590 : 0 : spin_unlock(&hash_lock);
591 : :
592 : 0 : untag_chunk(chunk, mark);
593 : 0 : fsnotify_put_mark(mark);
594 : :
595 : 0 : spin_lock(&hash_lock);
596 : : }
597 : 0 : spin_unlock(&hash_lock);
598 : 0 : put_tree(victim);
599 : 0 : }
600 : :
601 : : /*
602 : : * finish killing struct audit_tree
603 : : */
604 : 0 : static void prune_one(struct audit_tree *victim)
605 : : {
606 : 0 : prune_tree_chunks(victim, false);
607 : 0 : }
608 : :
609 : : /* trim the uncommitted chunks from tree */
610 : :
611 : 0 : static void trim_marked(struct audit_tree *tree)
612 : : {
613 : 0 : struct list_head *p, *q;
614 : 0 : spin_lock(&hash_lock);
615 [ # # ]: 0 : if (tree->goner) {
616 : 0 : spin_unlock(&hash_lock);
617 : 0 : return;
618 : : }
619 : : /* reorder */
620 [ # # ]: 0 : for (p = tree->chunks.next; p != &tree->chunks; p = q) {
621 : 0 : struct node *node = list_entry(p, struct node, list);
622 : 0 : q = p->next;
623 [ # # ]: 0 : if (node->index & (1U<<31)) {
624 : 0 : list_del_init(p);
625 : 0 : list_add(p, &tree->chunks);
626 : : }
627 : : }
628 : 0 : spin_unlock(&hash_lock);
629 : :
630 : 0 : prune_tree_chunks(tree, true);
631 : :
632 : 0 : spin_lock(&hash_lock);
633 [ # # # # ]: 0 : if (!tree->root && !tree->goner) {
634 : 0 : tree->goner = 1;
635 : 0 : spin_unlock(&hash_lock);
636 : 0 : mutex_lock(&audit_filter_mutex);
637 : 0 : kill_rules(audit_context(), tree);
638 : 0 : list_del_init(&tree->list);
639 : 0 : mutex_unlock(&audit_filter_mutex);
640 : 0 : prune_one(tree);
641 : : } else {
642 : 0 : spin_unlock(&hash_lock);
643 : : }
644 : : }
645 : :
646 : : static void audit_schedule_prune(void);
647 : :
648 : : /* called with audit_filter_mutex */
649 : 0 : int audit_remove_tree_rule(struct audit_krule *rule)
650 : : {
651 : 0 : struct audit_tree *tree;
652 : 0 : tree = rule->tree;
653 [ # # ]: 0 : if (tree) {
654 : 0 : spin_lock(&hash_lock);
655 [ # # ]: 0 : list_del_init(&rule->rlist);
656 [ # # # # ]: 0 : if (list_empty(&tree->rules) && !tree->goner) {
657 : 0 : tree->root = NULL;
658 : 0 : list_del_init(&tree->same_root);
659 : 0 : tree->goner = 1;
660 : 0 : list_move(&tree->list, &prune_list);
661 : 0 : rule->tree = NULL;
662 : 0 : spin_unlock(&hash_lock);
663 : 0 : audit_schedule_prune();
664 : 0 : return 1;
665 : : }
666 : 0 : rule->tree = NULL;
667 : 0 : spin_unlock(&hash_lock);
668 : 0 : return 1;
669 : : }
670 : : return 0;
671 : : }
672 : :
673 : 0 : static int compare_root(struct vfsmount *mnt, void *arg)
674 : : {
675 : 0 : return inode_to_key(d_backing_inode(mnt->mnt_root)) ==
676 : 0 : (unsigned long)arg;
677 : : }
678 : :
679 : 0 : void audit_trim_trees(void)
680 : : {
681 : 0 : struct list_head cursor;
682 : :
683 : 0 : mutex_lock(&audit_filter_mutex);
684 : 0 : list_add(&cursor, &tree_list);
685 [ # # ]: 0 : while (cursor.next != &tree_list) {
686 : 0 : struct audit_tree *tree;
687 : 0 : struct path path;
688 : 0 : struct vfsmount *root_mnt;
689 : 0 : struct node *node;
690 : 0 : int err;
691 : :
692 : 0 : tree = container_of(cursor.next, struct audit_tree, list);
693 : 0 : get_tree(tree);
694 : 0 : list_del(&cursor);
695 : 0 : list_add(&cursor, &tree->list);
696 : 0 : mutex_unlock(&audit_filter_mutex);
697 : :
698 : 0 : err = kern_path(tree->pathname, 0, &path);
699 [ # # ]: 0 : if (err)
700 : 0 : goto skip_it;
701 : :
702 : 0 : root_mnt = collect_mounts(&path);
703 : 0 : path_put(&path);
704 [ # # ]: 0 : if (IS_ERR(root_mnt))
705 : 0 : goto skip_it;
706 : :
707 : 0 : spin_lock(&hash_lock);
708 [ # # ]: 0 : list_for_each_entry(node, &tree->chunks, list) {
709 : 0 : struct audit_chunk *chunk = find_chunk(node);
710 : : /* this could be NULL if the watch is dying else where... */
711 : 0 : node->index |= 1U<<31;
712 [ # # ]: 0 : if (iterate_mounts(compare_root,
713 : 0 : (void *)(chunk->key),
714 : : root_mnt))
715 : 0 : node->index &= ~(1U<<31);
716 : : }
717 : 0 : spin_unlock(&hash_lock);
718 : 0 : trim_marked(tree);
719 : 0 : drop_collected_mounts(root_mnt);
720 : 0 : skip_it:
721 : 0 : put_tree(tree);
722 : 0 : mutex_lock(&audit_filter_mutex);
723 : : }
724 : 0 : list_del(&cursor);
725 : 0 : mutex_unlock(&audit_filter_mutex);
726 : 0 : }
727 : :
728 : 0 : int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
729 : : {
730 : :
731 [ # # ]: 0 : if (pathname[0] != '/' ||
732 [ # # # # ]: 0 : rule->listnr != AUDIT_FILTER_EXIT ||
733 : 0 : op != Audit_equal ||
734 [ # # # # : 0 : rule->inode_f || rule->watch || rule->tree)
# # ]
735 : : return -EINVAL;
736 : 0 : rule->tree = alloc_tree(pathname);
737 [ # # ]: 0 : if (!rule->tree)
738 : 0 : return -ENOMEM;
739 : : return 0;
740 : : }
741 : :
742 : 0 : void audit_put_tree(struct audit_tree *tree)
743 : : {
744 : 0 : put_tree(tree);
745 : 0 : }
746 : :
747 : 0 : static int tag_mount(struct vfsmount *mnt, void *arg)
748 : : {
749 : 0 : return tag_chunk(d_backing_inode(mnt->mnt_root), arg);
750 : : }
751 : :
752 : : /*
753 : : * That gets run when evict_chunk() ends up needing to kill audit_tree.
754 : : * Runs from a separate thread.
755 : : */
756 : 0 : static int prune_tree_thread(void *unused)
757 : : {
758 : 0 : for (;;) {
759 [ # # ]: 0 : if (list_empty(&prune_list)) {
760 : 0 : set_current_state(TASK_INTERRUPTIBLE);
761 : 0 : schedule();
762 : : }
763 : :
764 : 0 : audit_ctl_lock();
765 : 0 : mutex_lock(&audit_filter_mutex);
766 : :
767 [ # # ]: 0 : while (!list_empty(&prune_list)) {
768 : 0 : struct audit_tree *victim;
769 : :
770 : 0 : victim = list_entry(prune_list.next,
771 : : struct audit_tree, list);
772 : 0 : list_del_init(&victim->list);
773 : :
774 : 0 : mutex_unlock(&audit_filter_mutex);
775 : :
776 : 0 : prune_one(victim);
777 : :
778 : 0 : mutex_lock(&audit_filter_mutex);
779 : : }
780 : :
781 : 0 : mutex_unlock(&audit_filter_mutex);
782 : 0 : audit_ctl_unlock();
783 : : }
784 : : return 0;
785 : : }
786 : :
787 : 0 : static int audit_launch_prune(void)
788 : : {
789 [ # # ]: 0 : if (prune_thread)
790 : : return 0;
791 [ # # ]: 0 : prune_thread = kthread_run(prune_tree_thread, NULL,
792 : : "audit_prune_tree");
793 [ # # ]: 0 : if (IS_ERR(prune_thread)) {
794 : 0 : pr_err("cannot start thread audit_prune_tree");
795 : 0 : prune_thread = NULL;
796 : 0 : return -ENOMEM;
797 : : }
798 : : return 0;
799 : : }
800 : :
801 : : /* called with audit_filter_mutex */
802 : 0 : int audit_add_tree_rule(struct audit_krule *rule)
803 : : {
804 : 0 : struct audit_tree *seed = rule->tree, *tree;
805 : 0 : struct path path;
806 : 0 : struct vfsmount *mnt;
807 : 0 : int err;
808 : :
809 : 0 : rule->tree = NULL;
810 [ # # ]: 0 : list_for_each_entry(tree, &tree_list, list) {
811 [ # # ]: 0 : if (!strcmp(seed->pathname, tree->pathname)) {
812 : 0 : put_tree(seed);
813 : 0 : rule->tree = tree;
814 : 0 : list_add(&rule->rlist, &tree->rules);
815 : 0 : return 0;
816 : : }
817 : : }
818 : 0 : tree = seed;
819 : 0 : list_add(&tree->list, &tree_list);
820 : 0 : list_add(&rule->rlist, &tree->rules);
821 : : /* do not set rule->tree yet */
822 : 0 : mutex_unlock(&audit_filter_mutex);
823 : :
824 [ # # ]: 0 : if (unlikely(!prune_thread)) {
825 : 0 : err = audit_launch_prune();
826 [ # # ]: 0 : if (err)
827 : 0 : goto Err;
828 : : }
829 : :
830 : 0 : err = kern_path(tree->pathname, 0, &path);
831 [ # # ]: 0 : if (err)
832 : 0 : goto Err;
833 : 0 : mnt = collect_mounts(&path);
834 : 0 : path_put(&path);
835 [ # # ]: 0 : if (IS_ERR(mnt)) {
836 : 0 : err = PTR_ERR(mnt);
837 : 0 : goto Err;
838 : : }
839 : :
840 : 0 : get_tree(tree);
841 : 0 : err = iterate_mounts(tag_mount, tree, mnt);
842 : 0 : drop_collected_mounts(mnt);
843 : :
844 [ # # ]: 0 : if (!err) {
845 : 0 : struct node *node;
846 : 0 : spin_lock(&hash_lock);
847 [ # # ]: 0 : list_for_each_entry(node, &tree->chunks, list)
848 : 0 : node->index &= ~(1U<<31);
849 : 0 : spin_unlock(&hash_lock);
850 : : } else {
851 : 0 : trim_marked(tree);
852 : 0 : goto Err;
853 : : }
854 : :
855 : 0 : mutex_lock(&audit_filter_mutex);
856 [ # # ]: 0 : if (list_empty(&rule->rlist)) {
857 : 0 : put_tree(tree);
858 : 0 : return -ENOENT;
859 : : }
860 : 0 : rule->tree = tree;
861 : 0 : put_tree(tree);
862 : :
863 : 0 : return 0;
864 : 0 : Err:
865 : 0 : mutex_lock(&audit_filter_mutex);
866 : 0 : list_del_init(&tree->list);
867 : 0 : list_del_init(&tree->rules);
868 : 0 : put_tree(tree);
869 : 0 : return err;
870 : : }
871 : :
872 : 0 : int audit_tag_tree(char *old, char *new)
873 : : {
874 : 0 : struct list_head cursor, barrier;
875 : 0 : int failed = 0;
876 : 0 : struct path path1, path2;
877 : 0 : struct vfsmount *tagged;
878 : 0 : int err;
879 : :
880 : 0 : err = kern_path(new, 0, &path2);
881 [ # # ]: 0 : if (err)
882 : : return err;
883 : 0 : tagged = collect_mounts(&path2);
884 : 0 : path_put(&path2);
885 [ # # ]: 0 : if (IS_ERR(tagged))
886 : 0 : return PTR_ERR(tagged);
887 : :
888 : 0 : err = kern_path(old, 0, &path1);
889 [ # # ]: 0 : if (err) {
890 : 0 : drop_collected_mounts(tagged);
891 : 0 : return err;
892 : : }
893 : :
894 : 0 : mutex_lock(&audit_filter_mutex);
895 : 0 : list_add(&barrier, &tree_list);
896 : 0 : list_add(&cursor, &barrier);
897 : :
898 [ # # ]: 0 : while (cursor.next != &tree_list) {
899 : 0 : struct audit_tree *tree;
900 : 0 : int good_one = 0;
901 : :
902 : 0 : tree = container_of(cursor.next, struct audit_tree, list);
903 : 0 : get_tree(tree);
904 : 0 : list_del(&cursor);
905 : 0 : list_add(&cursor, &tree->list);
906 : 0 : mutex_unlock(&audit_filter_mutex);
907 : :
908 : 0 : err = kern_path(tree->pathname, 0, &path2);
909 [ # # ]: 0 : if (!err) {
910 : 0 : good_one = path_is_under(&path1, &path2);
911 : 0 : path_put(&path2);
912 : : }
913 : :
914 [ # # ]: 0 : if (!good_one) {
915 : 0 : put_tree(tree);
916 : 0 : mutex_lock(&audit_filter_mutex);
917 : 0 : continue;
918 : : }
919 : :
920 : 0 : failed = iterate_mounts(tag_mount, tree, tagged);
921 [ # # ]: 0 : if (failed) {
922 : 0 : put_tree(tree);
923 : 0 : mutex_lock(&audit_filter_mutex);
924 : 0 : break;
925 : : }
926 : :
927 : 0 : mutex_lock(&audit_filter_mutex);
928 : 0 : spin_lock(&hash_lock);
929 [ # # ]: 0 : if (!tree->goner) {
930 : 0 : list_del(&tree->list);
931 : 0 : list_add(&tree->list, &tree_list);
932 : : }
933 : 0 : spin_unlock(&hash_lock);
934 : 0 : put_tree(tree);
935 : : }
936 : :
937 [ # # ]: 0 : while (barrier.prev != &tree_list) {
938 : 0 : struct audit_tree *tree;
939 : :
940 : 0 : tree = container_of(barrier.prev, struct audit_tree, list);
941 : 0 : get_tree(tree);
942 : 0 : list_del(&tree->list);
943 : 0 : list_add(&tree->list, &barrier);
944 : 0 : mutex_unlock(&audit_filter_mutex);
945 : :
946 [ # # ]: 0 : if (!failed) {
947 : 0 : struct node *node;
948 : 0 : spin_lock(&hash_lock);
949 [ # # ]: 0 : list_for_each_entry(node, &tree->chunks, list)
950 : 0 : node->index &= ~(1U<<31);
951 : 0 : spin_unlock(&hash_lock);
952 : : } else {
953 : 0 : trim_marked(tree);
954 : : }
955 : :
956 : 0 : put_tree(tree);
957 : 0 : mutex_lock(&audit_filter_mutex);
958 : : }
959 : 0 : list_del(&barrier);
960 : 0 : list_del(&cursor);
961 : 0 : mutex_unlock(&audit_filter_mutex);
962 : 0 : path_put(&path1);
963 : 0 : drop_collected_mounts(tagged);
964 : 0 : return failed;
965 : : }
966 : :
967 : :
968 : 0 : static void audit_schedule_prune(void)
969 : : {
970 : 0 : wake_up_process(prune_thread);
971 : 0 : }
972 : :
973 : : /*
974 : : * ... and that one is done if evict_chunk() decides to delay until the end
975 : : * of syscall. Runs synchronously.
976 : : */
977 : 0 : void audit_kill_trees(struct audit_context *context)
978 : : {
979 : 0 : struct list_head *list = &context->killed_trees;
980 : :
981 : 0 : audit_ctl_lock();
982 : 0 : mutex_lock(&audit_filter_mutex);
983 : :
984 [ # # ]: 0 : while (!list_empty(list)) {
985 : 0 : struct audit_tree *victim;
986 : :
987 : 0 : victim = list_entry(list->next, struct audit_tree, list);
988 : 0 : kill_rules(context, victim);
989 : 0 : list_del_init(&victim->list);
990 : :
991 : 0 : mutex_unlock(&audit_filter_mutex);
992 : :
993 : 0 : prune_one(victim);
994 : :
995 : 0 : mutex_lock(&audit_filter_mutex);
996 : : }
997 : :
998 : 0 : mutex_unlock(&audit_filter_mutex);
999 : 0 : audit_ctl_unlock();
1000 : 0 : }
1001 : :
1002 : : /*
1003 : : * Here comes the stuff asynchronous to auditctl operations
1004 : : */
1005 : :
1006 : 0 : static void evict_chunk(struct audit_chunk *chunk)
1007 : : {
1008 : 0 : struct audit_tree *owner;
1009 : 0 : struct list_head *postponed = audit_killed_trees();
1010 : 0 : int need_prune = 0;
1011 : 0 : int n;
1012 : :
1013 : 0 : mutex_lock(&audit_filter_mutex);
1014 : 0 : spin_lock(&hash_lock);
1015 [ # # ]: 0 : while (!list_empty(&chunk->trees)) {
1016 : 0 : owner = list_entry(chunk->trees.next,
1017 : : struct audit_tree, same_root);
1018 : 0 : owner->goner = 1;
1019 : 0 : owner->root = NULL;
1020 : 0 : list_del_init(&owner->same_root);
1021 : 0 : spin_unlock(&hash_lock);
1022 [ # # ]: 0 : if (!postponed) {
1023 : 0 : kill_rules(audit_context(), owner);
1024 : 0 : list_move(&owner->list, &prune_list);
1025 : 0 : need_prune = 1;
1026 : : } else {
1027 : 0 : list_move(&owner->list, postponed);
1028 : : }
1029 : 0 : spin_lock(&hash_lock);
1030 : : }
1031 : 0 : list_del_rcu(&chunk->hash);
1032 [ # # ]: 0 : for (n = 0; n < chunk->count; n++)
1033 : 0 : list_del_init(&chunk->owners[n].list);
1034 : 0 : spin_unlock(&hash_lock);
1035 : 0 : mutex_unlock(&audit_filter_mutex);
1036 [ # # ]: 0 : if (need_prune)
1037 : 0 : audit_schedule_prune();
1038 : 0 : }
1039 : :
1040 : 0 : static int audit_tree_handle_event(struct fsnotify_group *group,
1041 : : struct inode *to_tell,
1042 : : u32 mask, const void *data, int data_type,
1043 : : const struct qstr *file_name, u32 cookie,
1044 : : struct fsnotify_iter_info *iter_info)
1045 : : {
1046 : 0 : return 0;
1047 : : }
1048 : :
1049 : 0 : static void audit_tree_freeing_mark(struct fsnotify_mark *mark,
1050 : : struct fsnotify_group *group)
1051 : : {
1052 : 0 : struct audit_chunk *chunk;
1053 : :
1054 : 0 : mutex_lock(&mark->group->mark_mutex);
1055 : 0 : spin_lock(&hash_lock);
1056 : 0 : chunk = mark_chunk(mark);
1057 : 0 : replace_mark_chunk(mark, NULL);
1058 : 0 : spin_unlock(&hash_lock);
1059 : 0 : mutex_unlock(&mark->group->mark_mutex);
1060 [ # # ]: 0 : if (chunk) {
1061 : 0 : evict_chunk(chunk);
1062 : 0 : audit_mark_put_chunk(chunk);
1063 : : }
1064 : :
1065 : : /*
1066 : : * We are guaranteed to have at least one reference to the mark from
1067 : : * either the inode or the caller of fsnotify_destroy_mark().
1068 : : */
1069 [ # # ]: 0 : BUG_ON(refcount_read(&mark->refcnt) < 1);
1070 : 0 : }
1071 : :
1072 : : static const struct fsnotify_ops audit_tree_ops = {
1073 : : .handle_event = audit_tree_handle_event,
1074 : : .freeing_mark = audit_tree_freeing_mark,
1075 : : .free_mark = audit_tree_destroy_watch,
1076 : : };
1077 : :
1078 : 11 : static int __init audit_tree_init(void)
1079 : : {
1080 : 11 : int i;
1081 : :
1082 : 11 : audit_tree_mark_cachep = KMEM_CACHE(audit_tree_mark, SLAB_PANIC);
1083 : :
1084 : 11 : audit_tree_group = fsnotify_alloc_group(&audit_tree_ops);
1085 [ - + ]: 11 : if (IS_ERR(audit_tree_group))
1086 : 0 : audit_panic("cannot initialize fsnotify group for rectree watches");
1087 : :
1088 [ + + ]: 1419 : for (i = 0; i < HASH_SIZE; i++)
1089 : 1408 : INIT_LIST_HEAD(&chunk_hash_heads[i]);
1090 : :
1091 : 11 : return 0;
1092 : : }
1093 : : __initcall(audit_tree_init);
|