Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/apparmor/label.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* AppArmor security module
4
*
5
* This file contains AppArmor label definitions
6
*
7
* Copyright 2017 Canonical Ltd.
8
*/
9
10
#include <linux/audit.h>
11
#include <linux/seq_file.h>
12
#include <linux/sort.h>
13
14
#include "include/apparmor.h"
15
#include "include/cred.h"
16
#include "include/label.h"
17
#include "include/policy.h"
18
#include "include/secid.h"
19
20
21
/*
22
* the aa_label represents the set of profiles confining an object
23
*
24
* Labels maintain a reference count to the set of pointers they reference
25
* Labels are ref counted by
26
* tasks and object via the security field/security context off the field
27
* code - will take a ref count on a label if it needs the label
28
* beyond what is possible with an rcu_read_lock.
29
* profiles - each profile is a label
30
* secids - a pinned secid will keep a refcount of the label it is
31
* referencing
32
* objects - inode, files, sockets, ...
33
*
34
* Labels are not ref counted by the label set, so they maybe removed and
35
* freed when no longer in use.
36
*
37
*/
38
39
#define PROXY_POISON 97
40
#define LABEL_POISON 100
41
42
static void free_proxy(struct aa_proxy *proxy)
43
{
44
if (proxy) {
45
/* p->label will not updated any more as p is dead */
46
aa_put_label(rcu_dereference_protected(proxy->label, true));
47
memset(proxy, 0, sizeof(*proxy));
48
RCU_INIT_POINTER(proxy->label, (struct aa_label *)PROXY_POISON);
49
kfree(proxy);
50
}
51
}
52
53
void aa_proxy_kref(struct kref *kref)
54
{
55
struct aa_proxy *proxy = container_of(kref, struct aa_proxy, count);
56
57
free_proxy(proxy);
58
}
59
60
struct aa_proxy *aa_alloc_proxy(struct aa_label *label, gfp_t gfp)
61
{
62
struct aa_proxy *new;
63
64
new = kzalloc(sizeof(struct aa_proxy), gfp);
65
if (new) {
66
kref_init(&new->count);
67
rcu_assign_pointer(new->label, aa_get_label(label));
68
}
69
return new;
70
}
71
72
/* requires profile list write lock held */
73
void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new)
74
{
75
struct aa_label *tmp;
76
77
AA_BUG(!orig);
78
AA_BUG(!new);
79
lockdep_assert_held_write(&labels_set(orig)->lock);
80
81
tmp = rcu_dereference_protected(orig->proxy->label,
82
&labels_ns(orig)->lock);
83
rcu_assign_pointer(orig->proxy->label, aa_get_label(new));
84
orig->flags |= FLAG_STALE;
85
aa_put_label(tmp);
86
}
87
88
static void __proxy_share(struct aa_label *old, struct aa_label *new)
89
{
90
struct aa_proxy *proxy = new->proxy;
91
92
new->proxy = aa_get_proxy(old->proxy);
93
__aa_proxy_redirect(old, new);
94
aa_put_proxy(proxy);
95
}
96
97
98
/**
99
* ns_cmp - compare ns for label set ordering
100
* @a: ns to compare (NOT NULL)
101
* @b: ns to compare (NOT NULL)
102
*
103
* Returns: <0 if a < b
104
* ==0 if a == b
105
* >0 if a > b
106
*/
107
static int ns_cmp(struct aa_ns *a, struct aa_ns *b)
108
{
109
int res;
110
111
AA_BUG(!a);
112
AA_BUG(!b);
113
AA_BUG(!a->base.hname);
114
AA_BUG(!b->base.hname);
115
116
if (a == b)
117
return 0;
118
119
res = a->level - b->level;
120
if (res)
121
return res;
122
123
return strcmp(a->base.hname, b->base.hname);
124
}
125
126
/**
127
* profile_cmp - profile comparison for set ordering
128
* @a: profile to compare (NOT NULL)
129
* @b: profile to compare (NOT NULL)
130
*
131
* Returns: <0 if a < b
132
* ==0 if a == b
133
* >0 if a > b
134
*/
135
static int profile_cmp(struct aa_profile *a, struct aa_profile *b)
136
{
137
int res;
138
139
AA_BUG(!a);
140
AA_BUG(!b);
141
AA_BUG(!a->ns);
142
AA_BUG(!b->ns);
143
AA_BUG(!a->base.hname);
144
AA_BUG(!b->base.hname);
145
146
if (a == b || a->base.hname == b->base.hname)
147
return 0;
148
res = ns_cmp(a->ns, b->ns);
149
if (res)
150
return res;
151
152
return strcmp(a->base.hname, b->base.hname);
153
}
154
155
/**
156
* vec_cmp - label comparison for set ordering
157
* @a: aa_profile to compare (NOT NULL)
158
* @an: length of @a
159
* @b: aa_profile to compare (NOT NULL)
160
* @bn: length of @b
161
*
162
* Returns: <0 if @a < @b
163
* ==0 if @a == @b
164
* >0 if @a > @b
165
*/
166
static int vec_cmp(struct aa_profile **a, int an, struct aa_profile **b, int bn)
167
{
168
int i;
169
170
AA_BUG(!a);
171
AA_BUG(!*a);
172
AA_BUG(!b);
173
AA_BUG(!*b);
174
AA_BUG(an <= 0);
175
AA_BUG(bn <= 0);
176
177
for (i = 0; i < an && i < bn; i++) {
178
int res = profile_cmp(a[i], b[i]);
179
180
if (res != 0)
181
return res;
182
}
183
184
return an - bn;
185
}
186
187
static bool vec_is_stale(struct aa_profile **vec, int n)
188
{
189
int i;
190
191
AA_BUG(!vec);
192
193
for (i = 0; i < n; i++) {
194
if (profile_is_stale(vec[i]))
195
return true;
196
}
197
198
return false;
199
}
200
201
static void accum_label_info(struct aa_label *new)
202
{
203
long u = FLAG_UNCONFINED;
204
int i;
205
206
AA_BUG(!new);
207
208
/* size == 1 is a profile and flags must be set as part of creation */
209
if (new->size == 1)
210
return;
211
212
for (i = 0; i < new->size; i++) {
213
u |= new->vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 |
214
FLAG_STALE);
215
if (!(u & new->vec[i]->label.flags & FLAG_UNCONFINED))
216
u &= ~FLAG_UNCONFINED;
217
new->mediates |= new->vec[i]->label.mediates;
218
}
219
new->flags |= u;
220
}
221
222
static int sort_cmp(const void *a, const void *b)
223
{
224
return profile_cmp(*(struct aa_profile **)a, *(struct aa_profile **)b);
225
}
226
227
/*
228
* assumes vec is sorted
229
* Assumes @vec has null terminator at vec[n], and will null terminate
230
* vec[n - dups]
231
*/
232
static inline int unique(struct aa_profile **vec, int n)
233
{
234
int i, pos, dups = 0;
235
236
AA_BUG(n < 1);
237
AA_BUG(!vec);
238
239
pos = 0;
240
for (i = 1; i < n; i++) {
241
int res = profile_cmp(vec[pos], vec[i]);
242
243
AA_BUG(res > 0, "vec not sorted");
244
if (res == 0) {
245
/* drop duplicate */
246
aa_put_profile(vec[i]);
247
dups++;
248
continue;
249
}
250
pos++;
251
if (dups)
252
vec[pos] = vec[i];
253
}
254
255
AA_BUG(dups < 0);
256
257
return dups;
258
}
259
260
/**
261
* aa_vec_unique - canonical sort and unique a list of profiles
262
* @n: number of refcounted profiles in the list (@n > 0)
263
* @vec: list of profiles to sort and merge
264
* @flags: null terminator flags of @vec
265
*
266
* Returns: the number of duplicates eliminated == references put
267
*
268
* If @flags & VEC_FLAG_TERMINATE @vec has null terminator at vec[n], and will
269
* null terminate vec[n - dups]
270
*/
271
int aa_vec_unique(struct aa_profile **vec, int n, int flags)
272
{
273
int i, dups = 0;
274
275
AA_BUG(n < 1);
276
AA_BUG(!vec);
277
278
/* vecs are usually small and inorder, have a fallback for larger */
279
if (n > 8) {
280
sort(vec, n, sizeof(struct aa_profile *), sort_cmp, NULL);
281
dups = unique(vec, n);
282
goto out;
283
}
284
285
/* insertion sort + unique in one */
286
for (i = 1; i < n; i++) {
287
struct aa_profile *tmp = vec[i];
288
int pos, j;
289
290
for (pos = i - 1 - dups; pos >= 0; pos--) {
291
int res = profile_cmp(vec[pos], tmp);
292
293
if (res == 0) {
294
/* drop duplicate entry */
295
aa_put_profile(tmp);
296
dups++;
297
goto continue_outer;
298
} else if (res < 0)
299
break;
300
}
301
/* pos is at entry < tmp, or index -1. Set to insert pos */
302
pos++;
303
304
for (j = i - dups; j > pos; j--)
305
vec[j] = vec[j - 1];
306
vec[pos] = tmp;
307
continue_outer:
308
;
309
}
310
311
AA_BUG(dups < 0);
312
313
out:
314
if (flags & VEC_FLAG_TERMINATE)
315
vec[n - dups] = NULL;
316
317
return dups;
318
}
319
320
321
void aa_label_destroy(struct aa_label *label)
322
{
323
AA_BUG(!label);
324
325
if (!label_isprofile(label)) {
326
struct aa_profile *profile;
327
struct label_it i;
328
329
aa_put_str(label->hname);
330
331
label_for_each(i, label, profile) {
332
aa_put_profile(profile);
333
label->vec[i.i] = (struct aa_profile *)
334
(LABEL_POISON + (long) i.i);
335
}
336
}
337
338
if (label->proxy) {
339
if (rcu_dereference_protected(label->proxy->label, true) == label)
340
rcu_assign_pointer(label->proxy->label, NULL);
341
aa_put_proxy(label->proxy);
342
}
343
aa_free_secid(label->secid);
344
345
label->proxy = (struct aa_proxy *) PROXY_POISON + 1;
346
}
347
348
void aa_label_free(struct aa_label *label)
349
{
350
if (!label)
351
return;
352
353
aa_label_destroy(label);
354
kfree(label);
355
}
356
357
static void label_free_switch(struct aa_label *label)
358
{
359
if (label->flags & FLAG_NS_COUNT)
360
aa_free_ns(labels_ns(label));
361
else if (label_isprofile(label))
362
aa_free_profile(labels_profile(label));
363
else
364
aa_label_free(label);
365
}
366
367
static void label_free_rcu(struct rcu_head *head)
368
{
369
struct aa_label *label = container_of(head, struct aa_label, rcu);
370
371
if (label->flags & FLAG_IN_TREE)
372
(void) aa_label_remove(label);
373
label_free_switch(label);
374
}
375
376
void aa_label_kref(struct kref *kref)
377
{
378
struct aa_label *label = container_of(kref, struct aa_label, count);
379
struct aa_ns *ns = labels_ns(label);
380
381
if (!ns) {
382
/* never live, no rcu callback needed, just using the fn */
383
label_free_switch(label);
384
return;
385
}
386
/* TODO: update labels_profile macro so it works here */
387
AA_BUG(label_isprofile(label) &&
388
on_list_rcu(&label->vec[0]->base.profiles));
389
AA_BUG(label_isprofile(label) &&
390
on_list_rcu(&label->vec[0]->base.list));
391
392
/* TODO: if compound label and not stale add to reclaim cache */
393
call_rcu(&label->rcu, label_free_rcu);
394
}
395
396
static void label_free_or_put_new(struct aa_label *label, struct aa_label *new)
397
{
398
if (label != new)
399
/* need to free directly to break circular ref with proxy */
400
aa_label_free(new);
401
else
402
aa_put_label(new);
403
}
404
405
bool aa_label_init(struct aa_label *label, int size, gfp_t gfp)
406
{
407
AA_BUG(!label);
408
AA_BUG(size < 1);
409
410
if (aa_alloc_secid(label, gfp) < 0)
411
return false;
412
413
label->size = size; /* doesn't include null */
414
label->vec[size] = NULL; /* null terminate */
415
kref_init(&label->count);
416
RB_CLEAR_NODE(&label->node);
417
418
return true;
419
}
420
421
/**
422
* aa_label_alloc - allocate a label with a profile vector of @size length
423
* @size: size of profile vector in the label
424
* @proxy: proxy to use OR null if to allocate a new one
425
* @gfp: memory allocation type
426
*
427
* Returns: new label
428
* else NULL if failed
429
*/
430
struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp)
431
{
432
struct aa_label *new;
433
434
AA_BUG(size < 1);
435
436
/* + 1 for null terminator entry on vec */
437
new = kzalloc(struct_size(new, vec, size + 1), gfp);
438
AA_DEBUG(DEBUG_LABEL, "%s (%p)\n", __func__, new);
439
if (!new)
440
goto fail;
441
442
if (!aa_label_init(new, size, gfp))
443
goto fail;
444
445
if (!proxy) {
446
proxy = aa_alloc_proxy(new, gfp);
447
if (!proxy)
448
goto fail;
449
} else
450
aa_get_proxy(proxy);
451
/* just set new's proxy, don't redirect proxy here if it was passed in*/
452
new->proxy = proxy;
453
454
return new;
455
456
fail:
457
kfree(new);
458
459
return NULL;
460
}
461
462
463
/**
464
* label_cmp - label comparison for set ordering
465
* @a: label to compare (NOT NULL)
466
* @b: label to compare (NOT NULL)
467
*
468
* Returns: <0 if a < b
469
* ==0 if a == b
470
* >0 if a > b
471
*/
472
static int label_cmp(struct aa_label *a, struct aa_label *b)
473
{
474
AA_BUG(!b);
475
476
if (a == b)
477
return 0;
478
479
return vec_cmp(a->vec, a->size, b->vec, b->size);
480
}
481
482
/* helper fn for label_for_each_confined */
483
int aa_label_next_confined(struct aa_label *label, int i)
484
{
485
AA_BUG(!label);
486
AA_BUG(i < 0);
487
488
for (; i < label->size; i++) {
489
if (!profile_unconfined(label->vec[i]))
490
return i;
491
}
492
493
return i;
494
}
495
496
/**
497
* __aa_label_next_not_in_set - return the next profile of @sub not in @set
498
* @I: label iterator
499
* @set: label to test against
500
* @sub: label to if is subset of @set
501
*
502
* Returns: profile in @sub that is not in @set, with iterator set pos after
503
* else NULL if @sub is a subset of @set
504
*/
505
struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
506
struct aa_label *set,
507
struct aa_label *sub)
508
{
509
AA_BUG(!set);
510
AA_BUG(!I);
511
AA_BUG(I->i < 0);
512
AA_BUG(I->i > set->size);
513
AA_BUG(!sub);
514
AA_BUG(I->j < 0);
515
AA_BUG(I->j > sub->size);
516
517
while (I->j < sub->size && I->i < set->size) {
518
int res = profile_cmp(sub->vec[I->j], set->vec[I->i]);
519
520
if (res == 0) {
521
(I->j)++;
522
(I->i)++;
523
} else if (res > 0)
524
(I->i)++;
525
else
526
return sub->vec[(I->j)++];
527
}
528
529
if (I->j < sub->size)
530
return sub->vec[(I->j)++];
531
532
return NULL;
533
}
534
535
/**
536
* aa_label_is_subset - test if @sub is a subset of @set
537
* @set: label to test against
538
* @sub: label to test if is subset of @set
539
*
540
* Returns: true if @sub is subset of @set
541
* else false
542
*/
543
bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub)
544
{
545
struct label_it i = { };
546
547
AA_BUG(!set);
548
AA_BUG(!sub);
549
550
if (sub == set)
551
return true;
552
553
return __aa_label_next_not_in_set(&i, set, sub) == NULL;
554
}
555
556
/**
557
* aa_label_is_unconfined_subset - test if @sub is a subset of @set
558
* @set: label to test against
559
* @sub: label to test if is subset of @set
560
*
561
* This checks for subset but taking into account unconfined. IF
562
* @sub contains an unconfined profile that does not have a matching
563
* unconfined in @set then this will not cause the test to fail.
564
* Conversely we don't care about an unconfined in @set that is not in
565
* @sub
566
*
567
* Returns: true if @sub is special_subset of @set
568
* else false
569
*/
570
bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub)
571
{
572
struct label_it i = { };
573
struct aa_profile *p;
574
575
AA_BUG(!set);
576
AA_BUG(!sub);
577
578
if (sub == set)
579
return true;
580
581
do {
582
p = __aa_label_next_not_in_set(&i, set, sub);
583
if (p && !profile_unconfined(p))
584
break;
585
} while (p);
586
587
return p == NULL;
588
}
589
590
591
/**
592
* __label_remove - remove @label from the label set
593
* @label: label to remove
594
* @new: label to redirect to
595
*
596
* Requires: labels_set(@label)->lock write_lock
597
* Returns: true if the label was in the tree and removed
598
*/
599
static bool __label_remove(struct aa_label *label, struct aa_label *new)
600
{
601
struct aa_labelset *ls = labels_set(label);
602
603
AA_BUG(!ls);
604
AA_BUG(!label);
605
lockdep_assert_held_write(&ls->lock);
606
607
if (new)
608
__aa_proxy_redirect(label, new);
609
610
if (!label_is_stale(label))
611
__label_make_stale(label);
612
613
if (label->flags & FLAG_IN_TREE) {
614
rb_erase(&label->node, &ls->root);
615
label->flags &= ~FLAG_IN_TREE;
616
return true;
617
}
618
619
return false;
620
}
621
622
/**
623
* __label_replace - replace @old with @new in label set
624
* @old: label to remove from label set
625
* @new: label to replace @old with
626
*
627
* Requires: labels_set(@old)->lock write_lock
628
* valid ref count be held on @new
629
* Returns: true if @old was in set and replaced by @new
630
*
631
* Note: current implementation requires label set be order in such a way
632
* that @new directly replaces @old position in the set (ie.
633
* using pointer comparison of the label address would not work)
634
*/
635
static bool __label_replace(struct aa_label *old, struct aa_label *new)
636
{
637
struct aa_labelset *ls = labels_set(old);
638
639
AA_BUG(!ls);
640
AA_BUG(!old);
641
AA_BUG(!new);
642
lockdep_assert_held_write(&ls->lock);
643
AA_BUG(new->flags & FLAG_IN_TREE);
644
645
if (!label_is_stale(old))
646
__label_make_stale(old);
647
648
if (old->flags & FLAG_IN_TREE) {
649
rb_replace_node(&old->node, &new->node, &ls->root);
650
old->flags &= ~FLAG_IN_TREE;
651
new->flags |= FLAG_IN_TREE;
652
accum_label_info(new);
653
return true;
654
}
655
656
return false;
657
}
658
659
/**
660
* __label_insert - attempt to insert @l into a label set
661
* @ls: set of labels to insert @l into (NOT NULL)
662
* @label: new label to insert (NOT NULL)
663
* @replace: whether insertion should replace existing entry that is not stale
664
*
665
* Requires: @ls->lock
666
* caller to hold a valid ref on l
667
* if @replace is true l has a preallocated proxy associated
668
* Returns: @l if successful in inserting @l - with additional refcount
669
* else ref counted equivalent label that is already in the set,
670
* the else condition only happens if @replace is false
671
*/
672
static struct aa_label *__label_insert(struct aa_labelset *ls,
673
struct aa_label *label, bool replace)
674
{
675
struct rb_node **new, *parent = NULL;
676
677
AA_BUG(!ls);
678
AA_BUG(!label);
679
AA_BUG(labels_set(label) != ls);
680
lockdep_assert_held_write(&ls->lock);
681
AA_BUG(label->flags & FLAG_IN_TREE);
682
683
/* Figure out where to put new node */
684
new = &ls->root.rb_node;
685
while (*new) {
686
struct aa_label *this = rb_entry(*new, struct aa_label, node);
687
int result = label_cmp(label, this);
688
689
parent = *new;
690
if (result == 0) {
691
/* !__aa_get_label means queued for destruction,
692
* so replace in place, however the label has
693
* died before the replacement so do not share
694
* the proxy
695
*/
696
if (!replace && !label_is_stale(this)) {
697
if (__aa_get_label(this))
698
return this;
699
} else
700
__proxy_share(this, label);
701
AA_BUG(!__label_replace(this, label));
702
return aa_get_label(label);
703
} else if (result < 0)
704
new = &((*new)->rb_left);
705
else /* (result > 0) */
706
new = &((*new)->rb_right);
707
}
708
709
/* Add new node and rebalance tree. */
710
rb_link_node(&label->node, parent, new);
711
rb_insert_color(&label->node, &ls->root);
712
label->flags |= FLAG_IN_TREE;
713
accum_label_info(label);
714
715
return aa_get_label(label);
716
}
717
718
/**
719
* __vec_find - find label that matches @vec in label set
720
* @vec: vec of profiles to find matching label for (NOT NULL)
721
* @n: length of @vec
722
*
723
* Requires: @vec_labelset(vec) lock held
724
* caller to hold a valid ref on l
725
*
726
* Returns: ref counted @label if matching label is in tree
727
* ref counted label that is equiv to @l in tree
728
* else NULL if @vec equiv is not in tree
729
*/
730
static struct aa_label *__vec_find(struct aa_profile **vec, int n)
731
{
732
struct rb_node *node;
733
734
AA_BUG(!vec);
735
AA_BUG(!*vec);
736
AA_BUG(n <= 0);
737
738
node = vec_labelset(vec, n)->root.rb_node;
739
while (node) {
740
struct aa_label *this = rb_entry(node, struct aa_label, node);
741
int result = vec_cmp(this->vec, this->size, vec, n);
742
743
if (result > 0)
744
node = node->rb_left;
745
else if (result < 0)
746
node = node->rb_right;
747
else
748
return __aa_get_label(this);
749
}
750
751
return NULL;
752
}
753
754
/**
755
* __label_find - find label @label in label set
756
* @label: label to find (NOT NULL)
757
*
758
* Requires: labels_set(@label)->lock held
759
* caller to hold a valid ref on l
760
*
761
* Returns: ref counted @label if @label is in tree OR
762
* ref counted label that is equiv to @label in tree
763
* else NULL if @label or equiv is not in tree
764
*/
765
static struct aa_label *__label_find(struct aa_label *label)
766
{
767
AA_BUG(!label);
768
769
return __vec_find(label->vec, label->size);
770
}
771
772
773
/**
774
* aa_label_remove - remove a label from the labelset
775
* @label: label to remove
776
*
777
* Returns: true if @label was removed from the tree
778
* else @label was not in tree so it could not be removed
779
*/
780
bool aa_label_remove(struct aa_label *label)
781
{
782
struct aa_labelset *ls = labels_set(label);
783
unsigned long flags;
784
bool res;
785
786
AA_BUG(!ls);
787
788
write_lock_irqsave(&ls->lock, flags);
789
res = __label_remove(label, ns_unconfined(labels_ns(label)));
790
write_unlock_irqrestore(&ls->lock, flags);
791
792
return res;
793
}
794
795
/**
796
* aa_label_replace - replace a label @old with a new version @new
797
* @old: label to replace
798
* @new: label replacing @old
799
*
800
* Returns: true if @old was in tree and replaced
801
* else @old was not in tree, and @new was not inserted
802
*/
803
bool aa_label_replace(struct aa_label *old, struct aa_label *new)
804
{
805
unsigned long flags;
806
bool res;
807
808
if (name_is_shared(old, new) && labels_ns(old) == labels_ns(new)) {
809
write_lock_irqsave(&labels_set(old)->lock, flags);
810
if (old->proxy != new->proxy)
811
__proxy_share(old, new);
812
else
813
__aa_proxy_redirect(old, new);
814
res = __label_replace(old, new);
815
write_unlock_irqrestore(&labels_set(old)->lock, flags);
816
} else {
817
struct aa_label *l;
818
struct aa_labelset *ls = labels_set(old);
819
820
write_lock_irqsave(&ls->lock, flags);
821
res = __label_remove(old, new);
822
if (labels_ns(old) != labels_ns(new)) {
823
write_unlock_irqrestore(&ls->lock, flags);
824
ls = labels_set(new);
825
write_lock_irqsave(&ls->lock, flags);
826
}
827
l = __label_insert(ls, new, true);
828
res = (l == new);
829
write_unlock_irqrestore(&ls->lock, flags);
830
aa_put_label(l);
831
}
832
833
return res;
834
}
835
836
/**
837
* vec_find - find label @l in label set
838
* @vec: array of profiles to find equiv label for (NOT NULL)
839
* @n: length of @vec
840
*
841
* Returns: refcounted label if @vec equiv is in tree
842
* else NULL if @vec equiv is not in tree
843
*/
844
static struct aa_label *vec_find(struct aa_profile **vec, int n)
845
{
846
struct aa_labelset *ls;
847
struct aa_label *label;
848
unsigned long flags;
849
850
AA_BUG(!vec);
851
AA_BUG(!*vec);
852
AA_BUG(n <= 0);
853
854
ls = vec_labelset(vec, n);
855
read_lock_irqsave(&ls->lock, flags);
856
label = __vec_find(vec, n);
857
read_unlock_irqrestore(&ls->lock, flags);
858
859
return label;
860
}
861
862
/* requires sort and merge done first */
863
static struct aa_label *vec_create_and_insert_label(struct aa_profile **vec,
864
int len, gfp_t gfp)
865
{
866
struct aa_label *label = NULL;
867
struct aa_labelset *ls;
868
unsigned long flags;
869
struct aa_label *new;
870
int i;
871
872
AA_BUG(!vec);
873
874
if (len == 1)
875
return aa_get_label(&vec[0]->label);
876
877
ls = labels_set(&vec[len - 1]->label);
878
879
/* TODO: enable when read side is lockless
880
* check if label exists before taking locks
881
*/
882
new = aa_label_alloc(len, NULL, gfp);
883
if (!new)
884
return NULL;
885
886
for (i = 0; i < len; i++)
887
new->vec[i] = aa_get_profile(vec[i]);
888
889
write_lock_irqsave(&ls->lock, flags);
890
label = __label_insert(ls, new, false);
891
write_unlock_irqrestore(&ls->lock, flags);
892
label_free_or_put_new(label, new);
893
894
return label;
895
}
896
897
struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
898
gfp_t gfp)
899
{
900
struct aa_label *label = vec_find(vec, len);
901
902
if (label)
903
return label;
904
905
return vec_create_and_insert_label(vec, len, gfp);
906
}
907
908
909
/**
910
* aa_label_insert - insert label @label into @ls or return existing label
911
* @ls: labelset to insert @label into
912
* @label: label to insert
913
*
914
* Requires: caller to hold a valid ref on @label
915
*
916
* Returns: ref counted @label if successful in inserting @label
917
* else ref counted equivalent label that is already in the set
918
*/
919
struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *label)
920
{
921
struct aa_label *l;
922
unsigned long flags;
923
924
AA_BUG(!ls);
925
AA_BUG(!label);
926
927
/* check if label exists before taking lock */
928
if (!label_is_stale(label)) {
929
read_lock_irqsave(&ls->lock, flags);
930
l = __label_find(label);
931
read_unlock_irqrestore(&ls->lock, flags);
932
if (l)
933
return l;
934
}
935
936
write_lock_irqsave(&ls->lock, flags);
937
l = __label_insert(ls, label, false);
938
write_unlock_irqrestore(&ls->lock, flags);
939
940
return l;
941
}
942
943
944
/**
945
* aa_label_next_in_merge - find the next profile when merging @a and @b
946
* @I: label iterator
947
* @a: label to merge
948
* @b: label to merge
949
*
950
* Returns: next profile
951
* else null if no more profiles
952
*/
953
struct aa_profile *aa_label_next_in_merge(struct label_it *I,
954
struct aa_label *a,
955
struct aa_label *b)
956
{
957
AA_BUG(!a);
958
AA_BUG(!b);
959
AA_BUG(!I);
960
AA_BUG(I->i < 0);
961
AA_BUG(I->i > a->size);
962
AA_BUG(I->j < 0);
963
AA_BUG(I->j > b->size);
964
965
if (I->i < a->size) {
966
if (I->j < b->size) {
967
int res = profile_cmp(a->vec[I->i], b->vec[I->j]);
968
969
if (res > 0)
970
return b->vec[(I->j)++];
971
if (res == 0)
972
(I->j)++;
973
}
974
975
return a->vec[(I->i)++];
976
}
977
978
if (I->j < b->size)
979
return b->vec[(I->j)++];
980
981
return NULL;
982
}
983
984
/**
985
* label_merge_cmp - cmp of @a merging with @b against @z for set ordering
986
* @a: label to merge then compare (NOT NULL)
987
* @b: label to merge then compare (NOT NULL)
988
* @z: label to compare merge against (NOT NULL)
989
*
990
* Assumes: using the most recent versions of @a, @b, and @z
991
*
992
* Returns: <0 if a < b
993
* ==0 if a == b
994
* >0 if a > b
995
*/
996
static int label_merge_cmp(struct aa_label *a, struct aa_label *b,
997
struct aa_label *z)
998
{
999
struct aa_profile *p = NULL;
1000
struct label_it i = { };
1001
int k;
1002
1003
AA_BUG(!a);
1004
AA_BUG(!b);
1005
AA_BUG(!z);
1006
1007
for (k = 0;
1008
k < z->size && (p = aa_label_next_in_merge(&i, a, b));
1009
k++) {
1010
int res = profile_cmp(p, z->vec[k]);
1011
1012
if (res != 0)
1013
return res;
1014
}
1015
1016
if (p)
1017
return 1;
1018
else if (k < z->size)
1019
return -1;
1020
return 0;
1021
}
1022
1023
/**
1024
* label_merge_insert - create a new label by merging @a and @b
1025
* @new: preallocated label to merge into (NOT NULL)
1026
* @a: label to merge with @b (NOT NULL)
1027
* @b: label to merge with @a (NOT NULL)
1028
*
1029
* Requires: preallocated proxy
1030
*
1031
* Returns: ref counted label either @new if merge is unique
1032
* @a if @b is a subset of @a
1033
* @b if @a is a subset of @b
1034
*
1035
* NOTE: will not use @new if the merge results in @new == @a or @b
1036
*
1037
* Must be used within labelset write lock to avoid racing with
1038
* setting labels stale.
1039
*/
1040
static struct aa_label *label_merge_insert(struct aa_label *new,
1041
struct aa_label *a,
1042
struct aa_label *b)
1043
{
1044
struct aa_label *label;
1045
struct aa_labelset *ls;
1046
struct aa_profile *next;
1047
struct label_it i;
1048
unsigned long flags;
1049
int k = 0, invcount = 0;
1050
bool stale = false;
1051
1052
AA_BUG(!a);
1053
AA_BUG(a->size < 0);
1054
AA_BUG(!b);
1055
AA_BUG(b->size < 0);
1056
AA_BUG(!new);
1057
AA_BUG(new->size < a->size + b->size);
1058
1059
label_for_each_in_merge(i, a, b, next) {
1060
AA_BUG(!next);
1061
if (profile_is_stale(next)) {
1062
new->vec[k] = aa_get_newest_profile(next);
1063
AA_BUG(!new->vec[k]->label.proxy);
1064
AA_BUG(!new->vec[k]->label.proxy->label);
1065
if (next->label.proxy != new->vec[k]->label.proxy)
1066
invcount++;
1067
k++;
1068
stale = true;
1069
} else
1070
new->vec[k++] = aa_get_profile(next);
1071
}
1072
/* set to actual size which is <= allocated len */
1073
new->size = k;
1074
new->vec[k] = NULL;
1075
1076
if (invcount) {
1077
new->size -= aa_vec_unique(&new->vec[0], new->size,
1078
VEC_FLAG_TERMINATE);
1079
/* TODO: deal with reference labels */
1080
if (new->size == 1) {
1081
label = aa_get_label(&new->vec[0]->label);
1082
return label;
1083
}
1084
} else if (!stale) {
1085
/*
1086
* merge could be same as a || b, note: it is not possible
1087
* for new->size == a->size == b->size unless a == b
1088
*/
1089
if (k == a->size)
1090
return aa_get_label(a);
1091
else if (k == b->size)
1092
return aa_get_label(b);
1093
}
1094
ls = labels_set(new);
1095
write_lock_irqsave(&ls->lock, flags);
1096
label = __label_insert(labels_set(new), new, false);
1097
write_unlock_irqrestore(&ls->lock, flags);
1098
1099
return label;
1100
}
1101
1102
/**
1103
* labelset_of_merge - find which labelset a merged label should be inserted
1104
* @a: label to merge and insert
1105
* @b: label to merge and insert
1106
*
1107
* Returns: labelset that the merged label should be inserted into
1108
*/
1109
static struct aa_labelset *labelset_of_merge(struct aa_label *a,
1110
struct aa_label *b)
1111
{
1112
struct aa_ns *nsa = labels_ns(a);
1113
struct aa_ns *nsb = labels_ns(b);
1114
1115
if (ns_cmp(nsa, nsb) <= 0)
1116
return &nsa->labels;
1117
return &nsb->labels;
1118
}
1119
1120
/**
1121
* __label_find_merge - find label that is equiv to merge of @a and @b
1122
* @ls: set of labels to search (NOT NULL)
1123
* @a: label to merge with @b (NOT NULL)
1124
* @b: label to merge with @a (NOT NULL)
1125
*
1126
* Requires: ls->lock read_lock held
1127
*
1128
* Returns: ref counted label that is equiv to merge of @a and @b
1129
* else NULL if merge of @a and @b is not in set
1130
*/
1131
static struct aa_label *__label_find_merge(struct aa_labelset *ls,
1132
struct aa_label *a,
1133
struct aa_label *b)
1134
{
1135
struct rb_node *node;
1136
1137
AA_BUG(!ls);
1138
AA_BUG(!a);
1139
AA_BUG(!b);
1140
1141
if (a == b)
1142
return __label_find(a);
1143
1144
node = ls->root.rb_node;
1145
while (node) {
1146
struct aa_label *this = container_of(node, struct aa_label,
1147
node);
1148
int result = label_merge_cmp(a, b, this);
1149
1150
if (result < 0)
1151
node = node->rb_left;
1152
else if (result > 0)
1153
node = node->rb_right;
1154
else
1155
return __aa_get_label(this);
1156
}
1157
1158
return NULL;
1159
}
1160
1161
1162
/**
1163
* aa_label_find_merge - find label that is equiv to merge of @a and @b
1164
* @a: label to merge with @b (NOT NULL)
1165
* @b: label to merge with @a (NOT NULL)
1166
*
1167
* Requires: labels be fully constructed with a valid ns
1168
*
1169
* Returns: ref counted label that is equiv to merge of @a and @b
1170
* else NULL if merge of @a and @b is not in set
1171
*/
1172
struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b)
1173
{
1174
struct aa_labelset *ls;
1175
struct aa_label *label, *ar = NULL, *br = NULL;
1176
unsigned long flags;
1177
1178
AA_BUG(!a);
1179
AA_BUG(!b);
1180
1181
if (label_is_stale(a))
1182
a = ar = aa_get_newest_label(a);
1183
if (label_is_stale(b))
1184
b = br = aa_get_newest_label(b);
1185
ls = labelset_of_merge(a, b);
1186
read_lock_irqsave(&ls->lock, flags);
1187
label = __label_find_merge(ls, a, b);
1188
read_unlock_irqrestore(&ls->lock, flags);
1189
aa_put_label(ar);
1190
aa_put_label(br);
1191
1192
return label;
1193
}
1194
1195
/**
1196
* aa_label_merge - attempt to insert new merged label of @a and @b
1197
* @a: label to merge with @b (NOT NULL)
1198
* @b: label to merge with @a (NOT NULL)
1199
* @gfp: memory allocation type
1200
*
1201
* Requires: caller to hold valid refs on @a and @b
1202
* labels be fully constructed with a valid ns
1203
*
1204
* Returns: ref counted new label if successful in inserting merge of a & b
1205
* else ref counted equivalent label that is already in the set.
1206
* else NULL if could not create label (-ENOMEM)
1207
*/
1208
struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
1209
gfp_t gfp)
1210
{
1211
struct aa_label *label = NULL;
1212
1213
AA_BUG(!a);
1214
AA_BUG(!b);
1215
1216
if (a == b)
1217
return aa_get_newest_label(a);
1218
1219
/* TODO: enable when read side is lockless
1220
* check if label exists before taking locks
1221
if (!label_is_stale(a) && !label_is_stale(b))
1222
label = aa_label_find_merge(a, b);
1223
*/
1224
1225
if (!label) {
1226
struct aa_label *new;
1227
1228
a = aa_get_newest_label(a);
1229
b = aa_get_newest_label(b);
1230
1231
/* could use label_merge_len(a, b), but requires double
1232
* comparison for small savings
1233
*/
1234
new = aa_label_alloc(a->size + b->size, NULL, gfp);
1235
if (!new)
1236
goto out;
1237
1238
label = label_merge_insert(new, a, b);
1239
label_free_or_put_new(label, new);
1240
out:
1241
aa_put_label(a);
1242
aa_put_label(b);
1243
}
1244
1245
return label;
1246
}
1247
1248
/* match a profile and its associated ns component if needed
1249
* Assumes visibility test has already been done.
1250
* If a subns profile is not to be matched should be prescreened with
1251
* visibility test.
1252
*/
1253
static inline aa_state_t match_component(struct aa_profile *profile,
1254
struct aa_ruleset *rules,
1255
struct aa_profile *tp,
1256
aa_state_t state)
1257
{
1258
const char *ns_name;
1259
1260
if (profile->ns == tp->ns)
1261
return aa_dfa_match(rules->policy->dfa, state, tp->base.hname);
1262
1263
/* try matching with namespace name and then profile */
1264
ns_name = aa_ns_name(profile->ns, tp->ns, true);
1265
state = aa_dfa_match_len(rules->policy->dfa, state, ":", 1);
1266
state = aa_dfa_match(rules->policy->dfa, state, ns_name);
1267
state = aa_dfa_match_len(rules->policy->dfa, state, ":", 1);
1268
return aa_dfa_match(rules->policy->dfa, state, tp->base.hname);
1269
}
1270
1271
/**
1272
* label_compound_match - find perms for full compound label
1273
* @profile: profile to find perms for
1274
* @rules: ruleset to search
1275
* @label: label to check access permissions for
1276
* @state: state to start match in
1277
* @subns: whether to do permission checks on components in a subns
1278
* @request: permissions to request
1279
* @perms: perms struct to set
1280
*
1281
* Returns: 0 on success else ERROR
1282
*
1283
* For the label A//&B//&C this does the perm match for A//&B//&C
1284
* @perms should be preinitialized with allperms OR a previous permission
1285
* check to be stacked.
1286
*/
1287
static int label_compound_match(struct aa_profile *profile,
1288
struct aa_ruleset *rules,
1289
struct aa_label *label,
1290
aa_state_t state, bool subns, u32 request,
1291
struct aa_perms *perms)
1292
{
1293
struct aa_profile *tp;
1294
struct label_it i;
1295
1296
/* find first subcomponent that is visible */
1297
label_for_each(i, label, tp) {
1298
if (!aa_ns_visible(profile->ns, tp->ns, subns))
1299
continue;
1300
state = match_component(profile, rules, tp, state);
1301
if (!state)
1302
goto fail;
1303
goto next;
1304
}
1305
1306
/* no component visible */
1307
*perms = allperms;
1308
return 0;
1309
1310
next:
1311
label_for_each_cont(i, label, tp) {
1312
if (!aa_ns_visible(profile->ns, tp->ns, subns))
1313
continue;
1314
state = aa_dfa_match(rules->policy->dfa, state, "//&");
1315
state = match_component(profile, rules, tp, state);
1316
if (!state)
1317
goto fail;
1318
}
1319
*perms = *aa_lookup_perms(rules->policy, state);
1320
aa_apply_modes_to_perms(profile, perms);
1321
if ((perms->allow & request) != request)
1322
return -EACCES;
1323
1324
return 0;
1325
1326
fail:
1327
*perms = nullperms;
1328
return state;
1329
}
1330
1331
/**
1332
* label_components_match - find perms for all subcomponents of a label
1333
* @profile: profile to find perms for
1334
* @rules: ruleset to search
1335
* @label: label to check access permissions for
1336
* @start: state to start match in
1337
* @subns: whether to do permission checks on components in a subns
1338
* @request: permissions to request
1339
* @perms: an initialized perms struct to add accumulation to
1340
*
1341
* Returns: 0 on success else ERROR
1342
*
1343
* For the label A//&B//&C this does the perm match for each of A and B and C
1344
* @perms should be preinitialized with allperms OR a previous permission
1345
* check to be stacked.
1346
*/
1347
static int label_components_match(struct aa_profile *profile,
1348
struct aa_ruleset *rules,
1349
struct aa_label *label, aa_state_t start,
1350
bool subns, u32 request,
1351
struct aa_perms *perms)
1352
{
1353
struct aa_profile *tp;
1354
struct label_it i;
1355
struct aa_perms tmp;
1356
aa_state_t state = 0;
1357
1358
/* find first subcomponent to test */
1359
label_for_each(i, label, tp) {
1360
if (!aa_ns_visible(profile->ns, tp->ns, subns))
1361
continue;
1362
state = match_component(profile, rules, tp, start);
1363
if (!state)
1364
goto fail;
1365
goto next;
1366
}
1367
1368
/* no subcomponents visible - no change in perms */
1369
return 0;
1370
1371
next:
1372
tmp = *aa_lookup_perms(rules->policy, state);
1373
aa_apply_modes_to_perms(profile, &tmp);
1374
aa_perms_accum(perms, &tmp);
1375
label_for_each_cont(i, label, tp) {
1376
if (!aa_ns_visible(profile->ns, tp->ns, subns))
1377
continue;
1378
state = match_component(profile, rules, tp, start);
1379
if (!state)
1380
goto fail;
1381
tmp = *aa_lookup_perms(rules->policy, state);
1382
aa_apply_modes_to_perms(profile, &tmp);
1383
aa_perms_accum(perms, &tmp);
1384
}
1385
1386
if ((perms->allow & request) != request)
1387
return -EACCES;
1388
1389
return 0;
1390
1391
fail:
1392
*perms = nullperms;
1393
return -EACCES;
1394
}
1395
1396
/**
1397
* aa_label_match - do a multi-component label match
1398
* @profile: profile to match against (NOT NULL)
1399
* @rules: ruleset to search
1400
* @label: label to match (NOT NULL)
1401
* @state: state to start in
1402
* @subns: whether to match subns components
1403
* @request: permission request
1404
* @perms: Returns computed perms (NOT NULL)
1405
*
1406
* Returns: the state the match finished in, may be the none matching state
1407
*/
1408
int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
1409
struct aa_label *label, aa_state_t state, bool subns,
1410
u32 request, struct aa_perms *perms)
1411
{
1412
int error = label_compound_match(profile, rules, label, state, subns,
1413
request, perms);
1414
if (!error)
1415
return error;
1416
1417
*perms = allperms;
1418
return label_components_match(profile, rules, label, state, subns,
1419
request, perms);
1420
}
1421
1422
1423
/**
1424
* aa_update_label_name - update a label to have a stored name
1425
* @ns: ns being viewed from (NOT NULL)
1426
* @label: label to update (NOT NULL)
1427
* @gfp: type of memory allocation
1428
*
1429
* Requires: labels_set(label) not locked in caller
1430
*
1431
* note: only updates the label name if it does not have a name already
1432
* and if it is in the labelset
1433
*/
1434
bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
1435
{
1436
struct aa_labelset *ls;
1437
unsigned long flags;
1438
char __counted *name;
1439
bool res = false;
1440
1441
AA_BUG(!ns);
1442
AA_BUG(!label);
1443
1444
if (label->hname || labels_ns(label) != ns)
1445
return res;
1446
1447
if (aa_label_acntsxprint(&name, ns, label, FLAGS_NONE, gfp) < 0)
1448
return res;
1449
1450
ls = labels_set(label);
1451
write_lock_irqsave(&ls->lock, flags);
1452
if (!label->hname && label->flags & FLAG_IN_TREE) {
1453
label->hname = name;
1454
res = true;
1455
} else
1456
aa_put_str(name);
1457
write_unlock_irqrestore(&ls->lock, flags);
1458
1459
return res;
1460
}
1461
1462
/*
1463
* cached label name is present and visible
1464
* @label->hname only exists if label is namespace hierarchical
1465
*/
1466
static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label,
1467
int flags)
1468
{
1469
if (label->hname && (!ns || labels_ns(label) == ns) &&
1470
!(flags & ~FLAG_SHOW_MODE))
1471
return true;
1472
1473
return false;
1474
}
1475
1476
/* helper macro for snprint routines */
1477
#define update_for_len(total, len, size, str) \
1478
do { \
1479
size_t ulen = len; \
1480
\
1481
AA_BUG(len < 0); \
1482
total += ulen; \
1483
ulen = min(ulen, size); \
1484
size -= ulen; \
1485
str += ulen; \
1486
} while (0)
1487
1488
/**
1489
* aa_profile_snxprint - print a profile name to a buffer
1490
* @str: buffer to write to. (MAY BE NULL if @size == 0)
1491
* @size: size of buffer
1492
* @view: namespace profile is being viewed from
1493
* @profile: profile to view (NOT NULL)
1494
* @flags: whether to include the mode string
1495
* @prev_ns: last ns printed when used in compound print
1496
*
1497
* Returns: size of name written or would be written if larger than
1498
* available buffer
1499
*
1500
* Note: will not print anything if the profile is not visible
1501
*/
1502
static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view,
1503
struct aa_profile *profile, int flags,
1504
struct aa_ns **prev_ns)
1505
{
1506
const char *ns_name = NULL;
1507
1508
AA_BUG(!str && size != 0);
1509
AA_BUG(!profile);
1510
1511
if (!view)
1512
view = profiles_ns(profile);
1513
1514
if (view != profile->ns &&
1515
(!prev_ns || (*prev_ns != profile->ns))) {
1516
if (prev_ns)
1517
*prev_ns = profile->ns;
1518
ns_name = aa_ns_name(view, profile->ns,
1519
flags & FLAG_VIEW_SUBNS);
1520
if (ns_name == aa_hidden_ns_name) {
1521
if (flags & FLAG_HIDDEN_UNCONFINED)
1522
return snprintf(str, size, "%s", "unconfined");
1523
return snprintf(str, size, "%s", ns_name);
1524
}
1525
}
1526
1527
if ((flags & FLAG_SHOW_MODE) && profile != profile->ns->unconfined) {
1528
const char *modestr = aa_profile_mode_names[profile->mode];
1529
1530
if (ns_name)
1531
return snprintf(str, size, ":%s:%s (%s)", ns_name,
1532
profile->base.hname, modestr);
1533
return snprintf(str, size, "%s (%s)", profile->base.hname,
1534
modestr);
1535
}
1536
1537
if (ns_name)
1538
return snprintf(str, size, ":%s:%s", ns_name,
1539
profile->base.hname);
1540
return snprintf(str, size, "%s", profile->base.hname);
1541
}
1542
1543
static const char *label_modename(struct aa_ns *ns, struct aa_label *label,
1544
int flags)
1545
{
1546
struct aa_profile *profile;
1547
struct label_it i;
1548
int mode = -1, count = 0;
1549
1550
label_for_each(i, label, profile) {
1551
if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
1552
count++;
1553
if (profile == profile->ns->unconfined)
1554
/* special case unconfined so stacks with
1555
* unconfined don't report as mixed. ie.
1556
* profile_foo//&:ns1:unconfined (mixed)
1557
*/
1558
continue;
1559
if (mode == -1)
1560
mode = profile->mode;
1561
else if (mode != profile->mode)
1562
return "mixed";
1563
}
1564
}
1565
1566
if (count == 0)
1567
return "-";
1568
if (mode == -1)
1569
/* everything was unconfined */
1570
mode = APPARMOR_UNCONFINED;
1571
1572
return aa_profile_mode_names[mode];
1573
}
1574
1575
/* if any visible label is not unconfined the display_mode returns true */
1576
static inline bool display_mode(struct aa_ns *ns, struct aa_label *label,
1577
int flags)
1578
{
1579
if ((flags & FLAG_SHOW_MODE)) {
1580
struct aa_profile *profile;
1581
struct label_it i;
1582
1583
label_for_each(i, label, profile) {
1584
if (aa_ns_visible(ns, profile->ns,
1585
flags & FLAG_VIEW_SUBNS) &&
1586
profile != profile->ns->unconfined)
1587
return true;
1588
}
1589
/* only ns->unconfined in set of profiles in ns */
1590
return false;
1591
}
1592
1593
return false;
1594
}
1595
1596
/**
1597
* aa_label_snxprint - print a label name to a string buffer
1598
* @str: buffer to write to. (MAY BE NULL if @size == 0)
1599
* @size: size of buffer
1600
* @ns: namespace profile is being viewed from
1601
* @label: label to view (NOT NULL)
1602
* @flags: whether to include the mode string
1603
*
1604
* Returns: size of name written or would be written if larger than
1605
* available buffer
1606
*
1607
* Note: labels do not have to be strictly hierarchical to the ns as
1608
* objects may be shared across different namespaces and thus
1609
* pickup labeling from each ns. If a particular part of the
1610
* label is not visible it will just be excluded. And if none
1611
* of the label is visible "---" will be used.
1612
*/
1613
int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
1614
struct aa_label *label, int flags)
1615
{
1616
struct aa_profile *profile;
1617
struct aa_ns *prev_ns = NULL;
1618
struct label_it i;
1619
int count = 0, total = 0;
1620
ssize_t len;
1621
1622
AA_BUG(!str && size != 0);
1623
AA_BUG(!label);
1624
1625
if (DEBUG_ABS_ROOT && (flags & FLAG_ABS_ROOT)) {
1626
ns = root_ns;
1627
len = snprintf(str, size, "_");
1628
update_for_len(total, len, size, str);
1629
} else if (!ns) {
1630
ns = labels_ns(label);
1631
}
1632
1633
label_for_each(i, label, profile) {
1634
if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
1635
if (count > 0) {
1636
len = snprintf(str, size, "//&");
1637
update_for_len(total, len, size, str);
1638
}
1639
len = aa_profile_snxprint(str, size, ns, profile,
1640
flags & FLAG_VIEW_SUBNS,
1641
&prev_ns);
1642
update_for_len(total, len, size, str);
1643
count++;
1644
}
1645
}
1646
1647
if (count == 0) {
1648
if (flags & FLAG_HIDDEN_UNCONFINED)
1649
return snprintf(str, size, "%s", "unconfined");
1650
return snprintf(str, size, "%s", aa_hidden_ns_name);
1651
}
1652
1653
/* count == 1 && ... is for backwards compat where the mode
1654
* is not displayed for 'unconfined' in the current ns
1655
*/
1656
if (display_mode(ns, label, flags)) {
1657
len = snprintf(str, size, " (%s)",
1658
label_modename(ns, label, flags));
1659
update_for_len(total, len, size, str);
1660
}
1661
1662
return total;
1663
}
1664
#undef update_for_len
1665
1666
/**
1667
* aa_label_asxprint - allocate a string buffer and print label into it
1668
* @strp: Returns - the allocated buffer with the label name. (NOT NULL)
1669
* @ns: namespace profile is being viewed from
1670
* @label: label to view (NOT NULL)
1671
* @flags: flags controlling what label info is printed
1672
* @gfp: kernel memory allocation type
1673
*
1674
* Returns: size of name written or would be written if larger than
1675
* available buffer
1676
*/
1677
int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
1678
int flags, gfp_t gfp)
1679
{
1680
int size;
1681
1682
AA_BUG(!strp);
1683
AA_BUG(!label);
1684
1685
size = aa_label_snxprint(NULL, 0, ns, label, flags);
1686
if (size < 0)
1687
return size;
1688
1689
*strp = kmalloc(size + 1, gfp);
1690
if (!*strp)
1691
return -ENOMEM;
1692
return aa_label_snxprint(*strp, size + 1, ns, label, flags);
1693
}
1694
1695
/**
1696
* aa_label_acntsxprint - allocate a __counted string buffer and print label
1697
* @strp: buffer to write to.
1698
* @ns: namespace profile is being viewed from
1699
* @label: label to view (NOT NULL)
1700
* @flags: flags controlling what label info is printed
1701
* @gfp: kernel memory allocation type
1702
*
1703
* Returns: size of name written or would be written if larger than
1704
* available buffer
1705
*/
1706
int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
1707
struct aa_label *label, int flags, gfp_t gfp)
1708
{
1709
int size;
1710
1711
AA_BUG(!strp);
1712
AA_BUG(!label);
1713
1714
size = aa_label_snxprint(NULL, 0, ns, label, flags);
1715
if (size < 0)
1716
return size;
1717
1718
*strp = aa_str_alloc(size + 1, gfp);
1719
if (!*strp)
1720
return -ENOMEM;
1721
return aa_label_snxprint(*strp, size + 1, ns, label, flags);
1722
}
1723
1724
1725
void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
1726
struct aa_label *label, int flags, gfp_t gfp)
1727
{
1728
const char *str;
1729
char *name = NULL;
1730
int len;
1731
1732
AA_BUG(!ab);
1733
AA_BUG(!label);
1734
1735
if (!use_label_hname(ns, label, flags) ||
1736
display_mode(ns, label, flags)) {
1737
len = aa_label_asxprint(&name, ns, label, flags, gfp);
1738
if (len < 0) {
1739
AA_DEBUG(DEBUG_LABEL, "label print error");
1740
return;
1741
}
1742
str = name;
1743
} else {
1744
str = (char *) label->hname;
1745
len = strlen(str);
1746
}
1747
if (audit_string_contains_control(str, len))
1748
audit_log_n_hex(ab, str, len);
1749
else
1750
audit_log_n_string(ab, str, len);
1751
1752
kfree(name);
1753
}
1754
1755
void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
1756
struct aa_label *label, int flags, gfp_t gfp)
1757
{
1758
AA_BUG(!f);
1759
AA_BUG(!label);
1760
1761
if (!use_label_hname(ns, label, flags)) {
1762
char *str;
1763
int len;
1764
1765
len = aa_label_asxprint(&str, ns, label, flags, gfp);
1766
if (len < 0) {
1767
AA_DEBUG(DEBUG_LABEL, "label print error");
1768
return;
1769
}
1770
seq_puts(f, str);
1771
kfree(str);
1772
} else if (display_mode(ns, label, flags))
1773
seq_printf(f, "%s (%s)", label->hname,
1774
label_modename(ns, label, flags));
1775
else
1776
seq_puts(f, label->hname);
1777
}
1778
1779
void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
1780
gfp_t gfp)
1781
{
1782
AA_BUG(!label);
1783
1784
if (!use_label_hname(ns, label, flags)) {
1785
char *str;
1786
int len;
1787
1788
len = aa_label_asxprint(&str, ns, label, flags, gfp);
1789
if (len < 0) {
1790
AA_DEBUG(DEBUG_LABEL, "label print error");
1791
return;
1792
}
1793
pr_info("%s", str);
1794
kfree(str);
1795
} else if (display_mode(ns, label, flags))
1796
pr_info("%s (%s)", label->hname,
1797
label_modename(ns, label, flags));
1798
else
1799
pr_info("%s", label->hname);
1800
}
1801
1802
void aa_label_printk(struct aa_label *label, gfp_t gfp)
1803
{
1804
struct aa_ns *ns = aa_get_current_ns();
1805
1806
aa_label_xprintk(ns, label, FLAG_VIEW_SUBNS, gfp);
1807
aa_put_ns(ns);
1808
}
1809
1810
static int label_count_strn_entries(const char *str, size_t n)
1811
{
1812
const char *end = str + n;
1813
const char *split;
1814
int count = 1;
1815
1816
AA_BUG(!str);
1817
1818
for (split = aa_label_strn_split(str, end - str);
1819
split;
1820
split = aa_label_strn_split(str, end - str)) {
1821
count++;
1822
str = split + 3;
1823
}
1824
1825
return count;
1826
}
1827
1828
/*
1829
* ensure stacks with components like
1830
* :ns:A//&B
1831
* have :ns: applied to both 'A' and 'B' by making the lookup relative
1832
* to the base if the lookup specifies an ns, else making the stacked lookup
1833
* relative to the last embedded ns in the string.
1834
*/
1835
static struct aa_profile *fqlookupn_profile(struct aa_label *base,
1836
struct aa_label *currentbase,
1837
const char *str, size_t n)
1838
{
1839
const char *first = skipn_spaces(str, n);
1840
1841
if (first && *first == ':')
1842
return aa_fqlookupn_profile(base, str, n);
1843
1844
return aa_fqlookupn_profile(currentbase, str, n);
1845
}
1846
1847
/**
1848
* aa_label_strn_parse - parse, validate and convert a text string to a label
1849
* @base: base label to use for lookups (NOT NULL)
1850
* @str: null terminated text string (NOT NULL)
1851
* @n: length of str to parse, will stop at \0 if encountered before n
1852
* @gfp: allocation type
1853
* @create: true if should create compound labels if they don't exist
1854
* @force_stack: true if should stack even if no leading &
1855
*
1856
* Returns: the matching refcounted label if present
1857
* else ERRPTR
1858
*/
1859
struct aa_label *aa_label_strn_parse(struct aa_label *base, const char *str,
1860
size_t n, gfp_t gfp, bool create,
1861
bool force_stack)
1862
{
1863
DEFINE_VEC(profile, vec);
1864
struct aa_label *label, *currbase = base;
1865
int i, len, stack = 0, error;
1866
const char *end = str + n;
1867
const char *split;
1868
1869
AA_BUG(!base);
1870
AA_BUG(!str);
1871
1872
str = skipn_spaces(str, n);
1873
if (str == NULL || (DEBUG_ABS_ROOT && *str == '_' &&
1874
base != &root_ns->unconfined->label))
1875
return ERR_PTR(-EINVAL);
1876
1877
len = label_count_strn_entries(str, end - str);
1878
if (*str == '&' || force_stack) {
1879
/* stack on top of base */
1880
stack = base->size;
1881
len += stack;
1882
if (*str == '&')
1883
str++;
1884
}
1885
1886
error = vec_setup(profile, vec, len, gfp);
1887
if (error)
1888
return ERR_PTR(error);
1889
1890
for (i = 0; i < stack; i++)
1891
vec[i] = aa_get_profile(base->vec[i]);
1892
1893
for (split = aa_label_strn_split(str, end - str), i = stack;
1894
split && i < len; i++) {
1895
vec[i] = fqlookupn_profile(base, currbase, str, split - str);
1896
if (!vec[i])
1897
goto fail;
1898
/*
1899
* if component specified a new ns it becomes the new base
1900
* so that subsequent lookups are relative to it
1901
*/
1902
if (vec[i]->ns != labels_ns(currbase))
1903
currbase = &vec[i]->label;
1904
str = split + 3;
1905
split = aa_label_strn_split(str, end - str);
1906
}
1907
/* last element doesn't have a split */
1908
if (i < len) {
1909
vec[i] = fqlookupn_profile(base, currbase, str, end - str);
1910
if (!vec[i])
1911
goto fail;
1912
}
1913
if (len == 1)
1914
/* no need to free vec as len < LOCAL_VEC_ENTRIES */
1915
return &vec[0]->label;
1916
1917
len -= aa_vec_unique(vec, len, VEC_FLAG_TERMINATE);
1918
/* TODO: deal with reference labels */
1919
if (len == 1) {
1920
label = aa_get_label(&vec[0]->label);
1921
goto out;
1922
}
1923
1924
if (create)
1925
label = aa_vec_find_or_create_label(vec, len, gfp);
1926
else
1927
label = vec_find(vec, len);
1928
if (!label)
1929
goto fail;
1930
1931
out:
1932
/* use adjusted len from after vec_unique, not original */
1933
vec_cleanup(profile, vec, len);
1934
return label;
1935
1936
fail:
1937
label = ERR_PTR(-ENOENT);
1938
goto out;
1939
}
1940
1941
struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
1942
gfp_t gfp, bool create, bool force_stack)
1943
{
1944
return aa_label_strn_parse(base, str, strlen(str), gfp, create,
1945
force_stack);
1946
}
1947
1948
/**
1949
* aa_labelset_destroy - remove all labels from the label set
1950
* @ls: label set to cleanup (NOT NULL)
1951
*
1952
* Labels that are removed from the set may still exist beyond the set
1953
* being destroyed depending on their reference counting
1954
*/
1955
void aa_labelset_destroy(struct aa_labelset *ls)
1956
{
1957
struct rb_node *node;
1958
unsigned long flags;
1959
1960
AA_BUG(!ls);
1961
1962
write_lock_irqsave(&ls->lock, flags);
1963
for (node = rb_first(&ls->root); node; node = rb_first(&ls->root)) {
1964
struct aa_label *this = rb_entry(node, struct aa_label, node);
1965
1966
if (labels_ns(this) != root_ns)
1967
__label_remove(this,
1968
ns_unconfined(labels_ns(this)->parent));
1969
else
1970
__label_remove(this, NULL);
1971
}
1972
write_unlock_irqrestore(&ls->lock, flags);
1973
}
1974
1975
/*
1976
* @ls: labelset to init (NOT NULL)
1977
*/
1978
void aa_labelset_init(struct aa_labelset *ls)
1979
{
1980
AA_BUG(!ls);
1981
1982
rwlock_init(&ls->lock);
1983
ls->root = RB_ROOT;
1984
}
1985
1986
static struct aa_label *labelset_next_stale(struct aa_labelset *ls)
1987
{
1988
struct aa_label *label;
1989
struct rb_node *node;
1990
unsigned long flags;
1991
1992
AA_BUG(!ls);
1993
1994
read_lock_irqsave(&ls->lock, flags);
1995
1996
__labelset_for_each(ls, node) {
1997
label = rb_entry(node, struct aa_label, node);
1998
if ((label_is_stale(label) ||
1999
vec_is_stale(label->vec, label->size)) &&
2000
__aa_get_label(label))
2001
goto out;
2002
2003
}
2004
label = NULL;
2005
2006
out:
2007
read_unlock_irqrestore(&ls->lock, flags);
2008
2009
return label;
2010
}
2011
2012
/**
2013
* __label_update - insert updated version of @label into labelset
2014
* @label: the label to update/replace
2015
*
2016
* Returns: new label that is up to date
2017
* else NULL on failure
2018
*
2019
* Requires: @ns lock be held
2020
*
2021
* Note: worst case is the stale @label does not get updated and has
2022
* to be updated at a later time.
2023
*/
2024
static struct aa_label *__label_update(struct aa_label *label)
2025
{
2026
struct aa_label *new, *tmp;
2027
struct aa_labelset *ls;
2028
unsigned long flags;
2029
int i, invcount = 0;
2030
2031
AA_BUG(!label);
2032
AA_BUG(!mutex_is_locked(&labels_ns(label)->lock));
2033
2034
new = aa_label_alloc(label->size, label->proxy, GFP_KERNEL);
2035
if (!new)
2036
return NULL;
2037
2038
/*
2039
* while holding the ns_lock will stop profile replacement, removal,
2040
* and label updates, label merging and removal can be occurring
2041
*/
2042
ls = labels_set(label);
2043
write_lock_irqsave(&ls->lock, flags);
2044
for (i = 0; i < label->size; i++) {
2045
AA_BUG(!label->vec[i]);
2046
new->vec[i] = aa_get_newest_profile(label->vec[i]);
2047
AA_BUG(!new->vec[i]);
2048
AA_BUG(!new->vec[i]->label.proxy);
2049
AA_BUG(!new->vec[i]->label.proxy->label);
2050
if (new->vec[i]->label.proxy != label->vec[i]->label.proxy)
2051
invcount++;
2052
}
2053
2054
/* updated stale label by being removed/renamed from labelset */
2055
if (invcount) {
2056
new->size -= aa_vec_unique(&new->vec[0], new->size,
2057
VEC_FLAG_TERMINATE);
2058
/* TODO: deal with reference labels */
2059
if (new->size == 1) {
2060
tmp = aa_get_label(&new->vec[0]->label);
2061
AA_BUG(tmp == label);
2062
goto remove;
2063
}
2064
if (labels_set(label) != labels_set(new)) {
2065
write_unlock_irqrestore(&ls->lock, flags);
2066
tmp = aa_label_insert(labels_set(new), new);
2067
write_lock_irqsave(&ls->lock, flags);
2068
goto remove;
2069
}
2070
} else
2071
AA_BUG(labels_ns(label) != labels_ns(new));
2072
2073
tmp = __label_insert(labels_set(label), new, true);
2074
remove:
2075
/* ensure label is removed, and redirected correctly */
2076
__label_remove(label, tmp);
2077
write_unlock_irqrestore(&ls->lock, flags);
2078
label_free_or_put_new(tmp, new);
2079
2080
return tmp;
2081
}
2082
2083
/**
2084
* __labelset_update - update labels in @ns
2085
* @ns: namespace to update labels in (NOT NULL)
2086
*
2087
* Requires: @ns lock be held
2088
*
2089
* Walk the labelset ensuring that all labels are up to date and valid
2090
* Any label that has a stale component is marked stale and replaced and
2091
* by an updated version.
2092
*
2093
* If failures happen due to memory pressures then stale labels will
2094
* be left in place until the next pass.
2095
*/
2096
static void __labelset_update(struct aa_ns *ns)
2097
{
2098
struct aa_label *label;
2099
2100
AA_BUG(!ns);
2101
AA_BUG(!mutex_is_locked(&ns->lock));
2102
2103
do {
2104
label = labelset_next_stale(&ns->labels);
2105
if (label) {
2106
struct aa_label *l = __label_update(label);
2107
2108
aa_put_label(l);
2109
aa_put_label(label);
2110
}
2111
} while (label);
2112
}
2113
2114
/**
2115
* __aa_labelset_update_subtree - update all labels with a stale component
2116
* @ns: ns to start update at (NOT NULL)
2117
*
2118
* Requires: @ns lock be held
2119
*
2120
* Invalidates labels based on @p in @ns and any children namespaces.
2121
*/
2122
void __aa_labelset_update_subtree(struct aa_ns *ns)
2123
{
2124
struct aa_ns *child;
2125
2126
AA_BUG(!ns);
2127
AA_BUG(!mutex_is_locked(&ns->lock));
2128
2129
__labelset_update(ns);
2130
2131
list_for_each_entry(child, &ns->sub_ns, base.list) {
2132
mutex_lock_nested(&child->lock, child->level);
2133
__aa_labelset_update_subtree(child);
2134
mutex_unlock(&child->lock);
2135
}
2136
}
2137
2138