File Index
Files and directories
Sign in
FILE

label.c

File preview with syntax highlighting.

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