cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

label.c (52262B)


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