Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/kernel/audit_tree.c
10818 views
1
#include "audit.h"
2
#include <linux/fsnotify_backend.h>
3
#include <linux/namei.h>
4
#include <linux/mount.h>
5
#include <linux/kthread.h>
6
#include <linux/slab.h>
7
8
struct audit_tree;
9
struct audit_chunk;
10
11
struct audit_tree {
12
atomic_t count;
13
int goner;
14
struct audit_chunk *root;
15
struct list_head chunks;
16
struct list_head rules;
17
struct list_head list;
18
struct list_head same_root;
19
struct rcu_head head;
20
char pathname[];
21
};
22
23
struct audit_chunk {
24
struct list_head hash;
25
struct fsnotify_mark mark;
26
struct list_head trees; /* with root here */
27
int dead;
28
int count;
29
atomic_long_t refs;
30
struct rcu_head head;
31
struct node {
32
struct list_head list;
33
struct audit_tree *owner;
34
unsigned index; /* index; upper bit indicates 'will prune' */
35
} owners[];
36
};
37
38
static LIST_HEAD(tree_list);
39
static LIST_HEAD(prune_list);
40
41
/*
42
* One struct chunk is attached to each inode of interest.
43
* We replace struct chunk on tagging/untagging.
44
* Rules have pointer to struct audit_tree.
45
* Rules have struct list_head rlist forming a list of rules over
46
* the same tree.
47
* References to struct chunk are collected at audit_inode{,_child}()
48
* time and used in AUDIT_TREE rule matching.
49
* These references are dropped at the same time we are calling
50
* audit_free_names(), etc.
51
*
52
* Cyclic lists galore:
53
* tree.chunks anchors chunk.owners[].list hash_lock
54
* tree.rules anchors rule.rlist audit_filter_mutex
55
* chunk.trees anchors tree.same_root hash_lock
56
* chunk.hash is a hash with middle bits of watch.inode as
57
* a hash function. RCU, hash_lock
58
*
59
* tree is refcounted; one reference for "some rules on rules_list refer to
60
* it", one for each chunk with pointer to it.
61
*
62
* chunk is refcounted by embedded fsnotify_mark + .refs (non-zero refcount
63
* of watch contributes 1 to .refs).
64
*
65
* node.index allows to get from node.list to containing chunk.
66
* MSB of that sucker is stolen to mark taggings that we might have to
67
* revert - several operations have very unpleasant cleanup logics and
68
* that makes a difference. Some.
69
*/
70
71
static struct fsnotify_group *audit_tree_group;
72
73
static struct audit_tree *alloc_tree(const char *s)
74
{
75
struct audit_tree *tree;
76
77
tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
78
if (tree) {
79
atomic_set(&tree->count, 1);
80
tree->goner = 0;
81
INIT_LIST_HEAD(&tree->chunks);
82
INIT_LIST_HEAD(&tree->rules);
83
INIT_LIST_HEAD(&tree->list);
84
INIT_LIST_HEAD(&tree->same_root);
85
tree->root = NULL;
86
strcpy(tree->pathname, s);
87
}
88
return tree;
89
}
90
91
static inline void get_tree(struct audit_tree *tree)
92
{
93
atomic_inc(&tree->count);
94
}
95
96
static void __put_tree(struct rcu_head *rcu)
97
{
98
struct audit_tree *tree = container_of(rcu, struct audit_tree, head);
99
kfree(tree);
100
}
101
102
static inline void put_tree(struct audit_tree *tree)
103
{
104
if (atomic_dec_and_test(&tree->count))
105
call_rcu(&tree->head, __put_tree);
106
}
107
108
/* to avoid bringing the entire thing in audit.h */
109
const char *audit_tree_path(struct audit_tree *tree)
110
{
111
return tree->pathname;
112
}
113
114
static void free_chunk(struct audit_chunk *chunk)
115
{
116
int i;
117
118
for (i = 0; i < chunk->count; i++) {
119
if (chunk->owners[i].owner)
120
put_tree(chunk->owners[i].owner);
121
}
122
kfree(chunk);
123
}
124
125
void audit_put_chunk(struct audit_chunk *chunk)
126
{
127
if (atomic_long_dec_and_test(&chunk->refs))
128
free_chunk(chunk);
129
}
130
131
static void __put_chunk(struct rcu_head *rcu)
132
{
133
struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
134
audit_put_chunk(chunk);
135
}
136
137
static void audit_tree_destroy_watch(struct fsnotify_mark *entry)
138
{
139
struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark);
140
call_rcu(&chunk->head, __put_chunk);
141
}
142
143
static struct audit_chunk *alloc_chunk(int count)
144
{
145
struct audit_chunk *chunk;
146
size_t size;
147
int i;
148
149
size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node);
150
chunk = kzalloc(size, GFP_KERNEL);
151
if (!chunk)
152
return NULL;
153
154
INIT_LIST_HEAD(&chunk->hash);
155
INIT_LIST_HEAD(&chunk->trees);
156
chunk->count = count;
157
atomic_long_set(&chunk->refs, 1);
158
for (i = 0; i < count; i++) {
159
INIT_LIST_HEAD(&chunk->owners[i].list);
160
chunk->owners[i].index = i;
161
}
162
fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch);
163
return chunk;
164
}
165
166
enum {HASH_SIZE = 128};
167
static struct list_head chunk_hash_heads[HASH_SIZE];
168
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock);
169
170
static inline struct list_head *chunk_hash(const struct inode *inode)
171
{
172
unsigned long n = (unsigned long)inode / L1_CACHE_BYTES;
173
return chunk_hash_heads + n % HASH_SIZE;
174
}
175
176
/* hash_lock & entry->lock is held by caller */
177
static void insert_hash(struct audit_chunk *chunk)
178
{
179
struct fsnotify_mark *entry = &chunk->mark;
180
struct list_head *list;
181
182
if (!entry->i.inode)
183
return;
184
list = chunk_hash(entry->i.inode);
185
list_add_rcu(&chunk->hash, list);
186
}
187
188
/* called under rcu_read_lock */
189
struct audit_chunk *audit_tree_lookup(const struct inode *inode)
190
{
191
struct list_head *list = chunk_hash(inode);
192
struct audit_chunk *p;
193
194
list_for_each_entry_rcu(p, list, hash) {
195
/* mark.inode may have gone NULL, but who cares? */
196
if (p->mark.i.inode == inode) {
197
atomic_long_inc(&p->refs);
198
return p;
199
}
200
}
201
return NULL;
202
}
203
204
int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
205
{
206
int n;
207
for (n = 0; n < chunk->count; n++)
208
if (chunk->owners[n].owner == tree)
209
return 1;
210
return 0;
211
}
212
213
/* tagging and untagging inodes with trees */
214
215
static struct audit_chunk *find_chunk(struct node *p)
216
{
217
int index = p->index & ~(1U<<31);
218
p -= index;
219
return container_of(p, struct audit_chunk, owners[0]);
220
}
221
222
static void untag_chunk(struct node *p)
223
{
224
struct audit_chunk *chunk = find_chunk(p);
225
struct fsnotify_mark *entry = &chunk->mark;
226
struct audit_chunk *new = NULL;
227
struct audit_tree *owner;
228
int size = chunk->count - 1;
229
int i, j;
230
231
fsnotify_get_mark(entry);
232
233
spin_unlock(&hash_lock);
234
235
if (size)
236
new = alloc_chunk(size);
237
238
spin_lock(&entry->lock);
239
if (chunk->dead || !entry->i.inode) {
240
spin_unlock(&entry->lock);
241
if (new)
242
free_chunk(new);
243
goto out;
244
}
245
246
owner = p->owner;
247
248
if (!size) {
249
chunk->dead = 1;
250
spin_lock(&hash_lock);
251
list_del_init(&chunk->trees);
252
if (owner->root == chunk)
253
owner->root = NULL;
254
list_del_init(&p->list);
255
list_del_rcu(&chunk->hash);
256
spin_unlock(&hash_lock);
257
spin_unlock(&entry->lock);
258
fsnotify_destroy_mark(entry);
259
fsnotify_put_mark(entry);
260
goto out;
261
}
262
263
if (!new)
264
goto Fallback;
265
266
fsnotify_duplicate_mark(&new->mark, entry);
267
if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) {
268
free_chunk(new);
269
goto Fallback;
270
}
271
272
chunk->dead = 1;
273
spin_lock(&hash_lock);
274
list_replace_init(&chunk->trees, &new->trees);
275
if (owner->root == chunk) {
276
list_del_init(&owner->same_root);
277
owner->root = NULL;
278
}
279
280
for (i = j = 0; j <= size; i++, j++) {
281
struct audit_tree *s;
282
if (&chunk->owners[j] == p) {
283
list_del_init(&p->list);
284
i--;
285
continue;
286
}
287
s = chunk->owners[j].owner;
288
new->owners[i].owner = s;
289
new->owners[i].index = chunk->owners[j].index - j + i;
290
if (!s) /* result of earlier fallback */
291
continue;
292
get_tree(s);
293
list_replace_init(&chunk->owners[j].list, &new->owners[i].list);
294
}
295
296
list_replace_rcu(&chunk->hash, &new->hash);
297
list_for_each_entry(owner, &new->trees, same_root)
298
owner->root = new;
299
spin_unlock(&hash_lock);
300
spin_unlock(&entry->lock);
301
fsnotify_destroy_mark(entry);
302
fsnotify_put_mark(entry);
303
goto out;
304
305
Fallback:
306
// do the best we can
307
spin_lock(&hash_lock);
308
if (owner->root == chunk) {
309
list_del_init(&owner->same_root);
310
owner->root = NULL;
311
}
312
list_del_init(&p->list);
313
p->owner = NULL;
314
put_tree(owner);
315
spin_unlock(&hash_lock);
316
spin_unlock(&entry->lock);
317
out:
318
fsnotify_put_mark(entry);
319
spin_lock(&hash_lock);
320
}
321
322
static int create_chunk(struct inode *inode, struct audit_tree *tree)
323
{
324
struct fsnotify_mark *entry;
325
struct audit_chunk *chunk = alloc_chunk(1);
326
if (!chunk)
327
return -ENOMEM;
328
329
entry = &chunk->mark;
330
if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) {
331
free_chunk(chunk);
332
return -ENOSPC;
333
}
334
335
spin_lock(&entry->lock);
336
spin_lock(&hash_lock);
337
if (tree->goner) {
338
spin_unlock(&hash_lock);
339
chunk->dead = 1;
340
spin_unlock(&entry->lock);
341
fsnotify_destroy_mark(entry);
342
fsnotify_put_mark(entry);
343
return 0;
344
}
345
chunk->owners[0].index = (1U << 31);
346
chunk->owners[0].owner = tree;
347
get_tree(tree);
348
list_add(&chunk->owners[0].list, &tree->chunks);
349
if (!tree->root) {
350
tree->root = chunk;
351
list_add(&tree->same_root, &chunk->trees);
352
}
353
insert_hash(chunk);
354
spin_unlock(&hash_lock);
355
spin_unlock(&entry->lock);
356
return 0;
357
}
358
359
/* the first tagged inode becomes root of tree */
360
static int tag_chunk(struct inode *inode, struct audit_tree *tree)
361
{
362
struct fsnotify_mark *old_entry, *chunk_entry;
363
struct audit_tree *owner;
364
struct audit_chunk *chunk, *old;
365
struct node *p;
366
int n;
367
368
old_entry = fsnotify_find_inode_mark(audit_tree_group, inode);
369
if (!old_entry)
370
return create_chunk(inode, tree);
371
372
old = container_of(old_entry, struct audit_chunk, mark);
373
374
/* are we already there? */
375
spin_lock(&hash_lock);
376
for (n = 0; n < old->count; n++) {
377
if (old->owners[n].owner == tree) {
378
spin_unlock(&hash_lock);
379
fsnotify_put_mark(old_entry);
380
return 0;
381
}
382
}
383
spin_unlock(&hash_lock);
384
385
chunk = alloc_chunk(old->count + 1);
386
if (!chunk) {
387
fsnotify_put_mark(old_entry);
388
return -ENOMEM;
389
}
390
391
chunk_entry = &chunk->mark;
392
393
spin_lock(&old_entry->lock);
394
if (!old_entry->i.inode) {
395
/* old_entry is being shot, lets just lie */
396
spin_unlock(&old_entry->lock);
397
fsnotify_put_mark(old_entry);
398
free_chunk(chunk);
399
return -ENOENT;
400
}
401
402
fsnotify_duplicate_mark(chunk_entry, old_entry);
403
if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) {
404
spin_unlock(&old_entry->lock);
405
free_chunk(chunk);
406
fsnotify_put_mark(old_entry);
407
return -ENOSPC;
408
}
409
410
/* even though we hold old_entry->lock, this is safe since chunk_entry->lock could NEVER have been grabbed before */
411
spin_lock(&chunk_entry->lock);
412
spin_lock(&hash_lock);
413
414
/* we now hold old_entry->lock, chunk_entry->lock, and hash_lock */
415
if (tree->goner) {
416
spin_unlock(&hash_lock);
417
chunk->dead = 1;
418
spin_unlock(&chunk_entry->lock);
419
spin_unlock(&old_entry->lock);
420
421
fsnotify_destroy_mark(chunk_entry);
422
423
fsnotify_put_mark(chunk_entry);
424
fsnotify_put_mark(old_entry);
425
return 0;
426
}
427
list_replace_init(&old->trees, &chunk->trees);
428
for (n = 0, p = chunk->owners; n < old->count; n++, p++) {
429
struct audit_tree *s = old->owners[n].owner;
430
p->owner = s;
431
p->index = old->owners[n].index;
432
if (!s) /* result of fallback in untag */
433
continue;
434
get_tree(s);
435
list_replace_init(&old->owners[n].list, &p->list);
436
}
437
p->index = (chunk->count - 1) | (1U<<31);
438
p->owner = tree;
439
get_tree(tree);
440
list_add(&p->list, &tree->chunks);
441
list_replace_rcu(&old->hash, &chunk->hash);
442
list_for_each_entry(owner, &chunk->trees, same_root)
443
owner->root = chunk;
444
old->dead = 1;
445
if (!tree->root) {
446
tree->root = chunk;
447
list_add(&tree->same_root, &chunk->trees);
448
}
449
spin_unlock(&hash_lock);
450
spin_unlock(&chunk_entry->lock);
451
spin_unlock(&old_entry->lock);
452
fsnotify_destroy_mark(old_entry);
453
fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
454
fsnotify_put_mark(old_entry); /* and kill it */
455
return 0;
456
}
457
458
static void kill_rules(struct audit_tree *tree)
459
{
460
struct audit_krule *rule, *next;
461
struct audit_entry *entry;
462
struct audit_buffer *ab;
463
464
list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
465
entry = container_of(rule, struct audit_entry, rule);
466
467
list_del_init(&rule->rlist);
468
if (rule->tree) {
469
/* not a half-baked one */
470
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
471
audit_log_format(ab, "op=");
472
audit_log_string(ab, "remove rule");
473
audit_log_format(ab, " dir=");
474
audit_log_untrustedstring(ab, rule->tree->pathname);
475
audit_log_key(ab, rule->filterkey);
476
audit_log_format(ab, " list=%d res=1", rule->listnr);
477
audit_log_end(ab);
478
rule->tree = NULL;
479
list_del_rcu(&entry->list);
480
list_del(&entry->rule.list);
481
call_rcu(&entry->rcu, audit_free_rule_rcu);
482
}
483
}
484
}
485
486
/*
487
* finish killing struct audit_tree
488
*/
489
static void prune_one(struct audit_tree *victim)
490
{
491
spin_lock(&hash_lock);
492
while (!list_empty(&victim->chunks)) {
493
struct node *p;
494
495
p = list_entry(victim->chunks.next, struct node, list);
496
497
untag_chunk(p);
498
}
499
spin_unlock(&hash_lock);
500
put_tree(victim);
501
}
502
503
/* trim the uncommitted chunks from tree */
504
505
static void trim_marked(struct audit_tree *tree)
506
{
507
struct list_head *p, *q;
508
spin_lock(&hash_lock);
509
if (tree->goner) {
510
spin_unlock(&hash_lock);
511
return;
512
}
513
/* reorder */
514
for (p = tree->chunks.next; p != &tree->chunks; p = q) {
515
struct node *node = list_entry(p, struct node, list);
516
q = p->next;
517
if (node->index & (1U<<31)) {
518
list_del_init(p);
519
list_add(p, &tree->chunks);
520
}
521
}
522
523
while (!list_empty(&tree->chunks)) {
524
struct node *node;
525
526
node = list_entry(tree->chunks.next, struct node, list);
527
528
/* have we run out of marked? */
529
if (!(node->index & (1U<<31)))
530
break;
531
532
untag_chunk(node);
533
}
534
if (!tree->root && !tree->goner) {
535
tree->goner = 1;
536
spin_unlock(&hash_lock);
537
mutex_lock(&audit_filter_mutex);
538
kill_rules(tree);
539
list_del_init(&tree->list);
540
mutex_unlock(&audit_filter_mutex);
541
prune_one(tree);
542
} else {
543
spin_unlock(&hash_lock);
544
}
545
}
546
547
static void audit_schedule_prune(void);
548
549
/* called with audit_filter_mutex */
550
int audit_remove_tree_rule(struct audit_krule *rule)
551
{
552
struct audit_tree *tree;
553
tree = rule->tree;
554
if (tree) {
555
spin_lock(&hash_lock);
556
list_del_init(&rule->rlist);
557
if (list_empty(&tree->rules) && !tree->goner) {
558
tree->root = NULL;
559
list_del_init(&tree->same_root);
560
tree->goner = 1;
561
list_move(&tree->list, &prune_list);
562
rule->tree = NULL;
563
spin_unlock(&hash_lock);
564
audit_schedule_prune();
565
return 1;
566
}
567
rule->tree = NULL;
568
spin_unlock(&hash_lock);
569
return 1;
570
}
571
return 0;
572
}
573
574
static int compare_root(struct vfsmount *mnt, void *arg)
575
{
576
return mnt->mnt_root->d_inode == arg;
577
}
578
579
void audit_trim_trees(void)
580
{
581
struct list_head cursor;
582
583
mutex_lock(&audit_filter_mutex);
584
list_add(&cursor, &tree_list);
585
while (cursor.next != &tree_list) {
586
struct audit_tree *tree;
587
struct path path;
588
struct vfsmount *root_mnt;
589
struct node *node;
590
int err;
591
592
tree = container_of(cursor.next, struct audit_tree, list);
593
get_tree(tree);
594
list_del(&cursor);
595
list_add(&cursor, &tree->list);
596
mutex_unlock(&audit_filter_mutex);
597
598
err = kern_path(tree->pathname, 0, &path);
599
if (err)
600
goto skip_it;
601
602
root_mnt = collect_mounts(&path);
603
path_put(&path);
604
if (!root_mnt)
605
goto skip_it;
606
607
spin_lock(&hash_lock);
608
list_for_each_entry(node, &tree->chunks, list) {
609
struct audit_chunk *chunk = find_chunk(node);
610
/* this could be NULL if the watch is dying else where... */
611
struct inode *inode = chunk->mark.i.inode;
612
node->index |= 1U<<31;
613
if (iterate_mounts(compare_root, inode, root_mnt))
614
node->index &= ~(1U<<31);
615
}
616
spin_unlock(&hash_lock);
617
trim_marked(tree);
618
put_tree(tree);
619
drop_collected_mounts(root_mnt);
620
skip_it:
621
mutex_lock(&audit_filter_mutex);
622
}
623
list_del(&cursor);
624
mutex_unlock(&audit_filter_mutex);
625
}
626
627
int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
628
{
629
630
if (pathname[0] != '/' ||
631
rule->listnr != AUDIT_FILTER_EXIT ||
632
op != Audit_equal ||
633
rule->inode_f || rule->watch || rule->tree)
634
return -EINVAL;
635
rule->tree = alloc_tree(pathname);
636
if (!rule->tree)
637
return -ENOMEM;
638
return 0;
639
}
640
641
void audit_put_tree(struct audit_tree *tree)
642
{
643
put_tree(tree);
644
}
645
646
static int tag_mount(struct vfsmount *mnt, void *arg)
647
{
648
return tag_chunk(mnt->mnt_root->d_inode, arg);
649
}
650
651
/* called with audit_filter_mutex */
652
int audit_add_tree_rule(struct audit_krule *rule)
653
{
654
struct audit_tree *seed = rule->tree, *tree;
655
struct path path;
656
struct vfsmount *mnt;
657
int err;
658
659
list_for_each_entry(tree, &tree_list, list) {
660
if (!strcmp(seed->pathname, tree->pathname)) {
661
put_tree(seed);
662
rule->tree = tree;
663
list_add(&rule->rlist, &tree->rules);
664
return 0;
665
}
666
}
667
tree = seed;
668
list_add(&tree->list, &tree_list);
669
list_add(&rule->rlist, &tree->rules);
670
/* do not set rule->tree yet */
671
mutex_unlock(&audit_filter_mutex);
672
673
err = kern_path(tree->pathname, 0, &path);
674
if (err)
675
goto Err;
676
mnt = collect_mounts(&path);
677
path_put(&path);
678
if (!mnt) {
679
err = -ENOMEM;
680
goto Err;
681
}
682
683
get_tree(tree);
684
err = iterate_mounts(tag_mount, tree, mnt);
685
drop_collected_mounts(mnt);
686
687
if (!err) {
688
struct node *node;
689
spin_lock(&hash_lock);
690
list_for_each_entry(node, &tree->chunks, list)
691
node->index &= ~(1U<<31);
692
spin_unlock(&hash_lock);
693
} else {
694
trim_marked(tree);
695
goto Err;
696
}
697
698
mutex_lock(&audit_filter_mutex);
699
if (list_empty(&rule->rlist)) {
700
put_tree(tree);
701
return -ENOENT;
702
}
703
rule->tree = tree;
704
put_tree(tree);
705
706
return 0;
707
Err:
708
mutex_lock(&audit_filter_mutex);
709
list_del_init(&tree->list);
710
list_del_init(&tree->rules);
711
put_tree(tree);
712
return err;
713
}
714
715
int audit_tag_tree(char *old, char *new)
716
{
717
struct list_head cursor, barrier;
718
int failed = 0;
719
struct path path1, path2;
720
struct vfsmount *tagged;
721
int err;
722
723
err = kern_path(new, 0, &path2);
724
if (err)
725
return err;
726
tagged = collect_mounts(&path2);
727
path_put(&path2);
728
if (!tagged)
729
return -ENOMEM;
730
731
err = kern_path(old, 0, &path1);
732
if (err) {
733
drop_collected_mounts(tagged);
734
return err;
735
}
736
737
mutex_lock(&audit_filter_mutex);
738
list_add(&barrier, &tree_list);
739
list_add(&cursor, &barrier);
740
741
while (cursor.next != &tree_list) {
742
struct audit_tree *tree;
743
int good_one = 0;
744
745
tree = container_of(cursor.next, struct audit_tree, list);
746
get_tree(tree);
747
list_del(&cursor);
748
list_add(&cursor, &tree->list);
749
mutex_unlock(&audit_filter_mutex);
750
751
err = kern_path(tree->pathname, 0, &path2);
752
if (!err) {
753
good_one = path_is_under(&path1, &path2);
754
path_put(&path2);
755
}
756
757
if (!good_one) {
758
put_tree(tree);
759
mutex_lock(&audit_filter_mutex);
760
continue;
761
}
762
763
failed = iterate_mounts(tag_mount, tree, tagged);
764
if (failed) {
765
put_tree(tree);
766
mutex_lock(&audit_filter_mutex);
767
break;
768
}
769
770
mutex_lock(&audit_filter_mutex);
771
spin_lock(&hash_lock);
772
if (!tree->goner) {
773
list_del(&tree->list);
774
list_add(&tree->list, &tree_list);
775
}
776
spin_unlock(&hash_lock);
777
put_tree(tree);
778
}
779
780
while (barrier.prev != &tree_list) {
781
struct audit_tree *tree;
782
783
tree = container_of(barrier.prev, struct audit_tree, list);
784
get_tree(tree);
785
list_del(&tree->list);
786
list_add(&tree->list, &barrier);
787
mutex_unlock(&audit_filter_mutex);
788
789
if (!failed) {
790
struct node *node;
791
spin_lock(&hash_lock);
792
list_for_each_entry(node, &tree->chunks, list)
793
node->index &= ~(1U<<31);
794
spin_unlock(&hash_lock);
795
} else {
796
trim_marked(tree);
797
}
798
799
put_tree(tree);
800
mutex_lock(&audit_filter_mutex);
801
}
802
list_del(&barrier);
803
list_del(&cursor);
804
mutex_unlock(&audit_filter_mutex);
805
path_put(&path1);
806
drop_collected_mounts(tagged);
807
return failed;
808
}
809
810
/*
811
* That gets run when evict_chunk() ends up needing to kill audit_tree.
812
* Runs from a separate thread.
813
*/
814
static int prune_tree_thread(void *unused)
815
{
816
mutex_lock(&audit_cmd_mutex);
817
mutex_lock(&audit_filter_mutex);
818
819
while (!list_empty(&prune_list)) {
820
struct audit_tree *victim;
821
822
victim = list_entry(prune_list.next, struct audit_tree, list);
823
list_del_init(&victim->list);
824
825
mutex_unlock(&audit_filter_mutex);
826
827
prune_one(victim);
828
829
mutex_lock(&audit_filter_mutex);
830
}
831
832
mutex_unlock(&audit_filter_mutex);
833
mutex_unlock(&audit_cmd_mutex);
834
return 0;
835
}
836
837
static void audit_schedule_prune(void)
838
{
839
kthread_run(prune_tree_thread, NULL, "audit_prune_tree");
840
}
841
842
/*
843
* ... and that one is done if evict_chunk() decides to delay until the end
844
* of syscall. Runs synchronously.
845
*/
846
void audit_kill_trees(struct list_head *list)
847
{
848
mutex_lock(&audit_cmd_mutex);
849
mutex_lock(&audit_filter_mutex);
850
851
while (!list_empty(list)) {
852
struct audit_tree *victim;
853
854
victim = list_entry(list->next, struct audit_tree, list);
855
kill_rules(victim);
856
list_del_init(&victim->list);
857
858
mutex_unlock(&audit_filter_mutex);
859
860
prune_one(victim);
861
862
mutex_lock(&audit_filter_mutex);
863
}
864
865
mutex_unlock(&audit_filter_mutex);
866
mutex_unlock(&audit_cmd_mutex);
867
}
868
869
/*
870
* Here comes the stuff asynchronous to auditctl operations
871
*/
872
873
static void evict_chunk(struct audit_chunk *chunk)
874
{
875
struct audit_tree *owner;
876
struct list_head *postponed = audit_killed_trees();
877
int need_prune = 0;
878
int n;
879
880
if (chunk->dead)
881
return;
882
883
chunk->dead = 1;
884
mutex_lock(&audit_filter_mutex);
885
spin_lock(&hash_lock);
886
while (!list_empty(&chunk->trees)) {
887
owner = list_entry(chunk->trees.next,
888
struct audit_tree, same_root);
889
owner->goner = 1;
890
owner->root = NULL;
891
list_del_init(&owner->same_root);
892
spin_unlock(&hash_lock);
893
if (!postponed) {
894
kill_rules(owner);
895
list_move(&owner->list, &prune_list);
896
need_prune = 1;
897
} else {
898
list_move(&owner->list, postponed);
899
}
900
spin_lock(&hash_lock);
901
}
902
list_del_rcu(&chunk->hash);
903
for (n = 0; n < chunk->count; n++)
904
list_del_init(&chunk->owners[n].list);
905
spin_unlock(&hash_lock);
906
if (need_prune)
907
audit_schedule_prune();
908
mutex_unlock(&audit_filter_mutex);
909
}
910
911
static int audit_tree_handle_event(struct fsnotify_group *group,
912
struct fsnotify_mark *inode_mark,
913
struct fsnotify_mark *vfsmonut_mark,
914
struct fsnotify_event *event)
915
{
916
BUG();
917
return -EOPNOTSUPP;
918
}
919
920
static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify_group *group)
921
{
922
struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark);
923
924
evict_chunk(chunk);
925
fsnotify_put_mark(entry);
926
}
927
928
static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode,
929
struct fsnotify_mark *inode_mark,
930
struct fsnotify_mark *vfsmount_mark,
931
__u32 mask, void *data, int data_type)
932
{
933
return false;
934
}
935
936
static const struct fsnotify_ops audit_tree_ops = {
937
.handle_event = audit_tree_handle_event,
938
.should_send_event = audit_tree_send_event,
939
.free_group_priv = NULL,
940
.free_event_priv = NULL,
941
.freeing_mark = audit_tree_freeing_mark,
942
};
943
944
static int __init audit_tree_init(void)
945
{
946
int i;
947
948
audit_tree_group = fsnotify_alloc_group(&audit_tree_ops);
949
if (IS_ERR(audit_tree_group))
950
audit_panic("cannot initialize fsnotify group for rectree watches");
951
952
for (i = 0; i < HASH_SIZE; i++)
953
INIT_LIST_HEAD(&chunk_hash_heads[i]);
954
955
return 0;
956
}
957
__initcall(audit_tree_init);
958
959