Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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