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 policy manipulation functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 1998-2008 Novell/SUSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright 2009-2017 Canonical Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * AppArmor policy namespaces, allow for different sets of policies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * to be loaded for tasks within the namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "include/apparmor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "include/cred.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "include/policy_ns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "include/label.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "include/policy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /* root profile namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct aa_ns *root_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) const char *aa_hidden_ns_name = "---";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * aa_ns_visible - test if @view is visible from @curr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * @curr: namespace to treat as the parent (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * @view: namespace to test if visible from @curr (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * @subns: whether view of a subns is allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * Returns: true if @view is visible from @curr else false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (curr == view)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (!subns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	for ( ; view; view = view->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		if (view->parent == curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	return false;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * aa_na_name - Find the ns name to display for @view from @curr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * @curr - current namespace (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * @view - namespace attempting to view (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * @subns - are subns visible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * Returns: name of @view visible from @curr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) const char *aa_ns_name(struct aa_ns *curr, struct aa_ns *view, bool subns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	/* if view == curr then the namespace name isn't displayed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (curr == view)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if (aa_ns_visible(curr, view, subns)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		/* at this point if a ns is visible it is in a view ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		 * thus the curr ns.hname is a prefix of its name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		 * Only output the virtualized portion of the name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		 * Add + 2 to skip over // separating curr hname prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		 * from the visible tail of the views hname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return view->base.hname + strlen(curr->base.hname) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return aa_hidden_ns_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * alloc_ns - allocate, initialize and return a new namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * @prefix: parent namespace name (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * @name: a preallocated name  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * Returns: refcounted namespace or NULL on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static struct aa_ns *alloc_ns(const char *prefix, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct aa_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	ns = kzalloc(sizeof(*ns), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	AA_DEBUG("%s(%p)\n", __func__, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (!aa_policy_init(&ns->base, prefix, name, GFP_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		goto fail_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	INIT_LIST_HEAD(&ns->sub_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	INIT_LIST_HEAD(&ns->rawdata_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	mutex_init(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	init_waitqueue_head(&ns->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	/* released by aa_free_ns() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	ns->unconfined = aa_alloc_profile("unconfined", NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (!ns->unconfined)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		goto fail_unconfined;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	ns->unconfined->mode = APPARMOR_UNCONFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	ns->unconfined->file.dfa = aa_get_dfa(nulldfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	ns->unconfined->policy.dfa = aa_get_dfa(nulldfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	/* ns and ns->unconfined share ns->unconfined refcount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	ns->unconfined->ns = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	atomic_set(&ns->uniq_null, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	aa_labelset_init(&ns->labels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) fail_unconfined:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	kfree_sensitive(ns->base.hname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) fail_ns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	kfree_sensitive(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * aa_free_ns - free a profile namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * @ns: the namespace to free  (MAYBE NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * Requires: All references to the namespace must have been put, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *           namespace was referenced by a profile confining a task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) void aa_free_ns(struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	aa_policy_destroy(&ns->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	aa_labelset_destroy(&ns->labels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	aa_put_ns(ns->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	ns->unconfined->ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	aa_free_profile(ns->unconfined);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	kfree_sensitive(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * aa_findn_ns  -  look up a profile namespace on the namespace list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * @root: namespace to search in  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  * @name: name of namespace to find  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * @n: length of @name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * Returns: a refcounted namespace on the list, or NULL if no namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  *          called @name exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * refcount released by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct aa_ns *ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	ns = aa_get_ns(__aa_findn_ns(&root->sub_ns, name, n));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * aa_find_ns  -  look up a profile namespace on the namespace list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @root: namespace to search in  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @name: name of namespace to find  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * Returns: a refcounted namespace on the list, or NULL if no namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  *          called @name exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * refcount released by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	return aa_findn_ns(root, name, strlen(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * __aa_lookupn_ns - lookup the namespace matching @hname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * @base: base list to start looking up profile name from  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * @hname: hierarchical ns name  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * @n: length of @hname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * Requires: rcu_read_lock be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  * Returns: unrefcounted ns pointer or NULL if not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * Do a relative name lookup, recursing through profile tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	struct aa_ns *ns = view;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	const char *split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	for (split = strnstr(hname, "//", n); split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	     split = strnstr(hname, "//", n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		ns = __aa_findn_ns(&ns->sub_ns, hname, split - hname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		n -= split + 2 - hname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		hname = split + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		return __aa_findn_ns(&ns->sub_ns, hname, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	return NULL;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * aa_lookupn_ns  -  look up a policy namespace relative to @view
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * @view: namespace to search in  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * @name: name of namespace to find  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * @n: length of @name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * Returns: a refcounted namespace on the list, or NULL if no namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  *          called @name exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * refcount released by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	struct aa_ns *ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	ns = aa_get_ns(__aa_lookupn_ns(view, name, n));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 				    struct dentry *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	struct aa_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	AA_BUG(!parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	AA_BUG(!name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	AA_BUG(!mutex_is_locked(&parent->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	ns = alloc_ns(parent->base.hname, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	ns->level = parent->level + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	mutex_lock_nested(&ns->lock, ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		AA_ERROR("Failed to create interface for ns %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			 ns->base.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		mutex_unlock(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		aa_free_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	ns->parent = aa_get_ns(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	list_add_rcu(&ns->base.list, &parent->sub_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	/* add list ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	aa_get_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	mutex_unlock(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * aa_create_ns - create an ns, fail if it already exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * @parent: the parent of the namespace being created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * @name: the name of the namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  * @dir: if not null the dir to put the ns entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * Returns: the a refcounted ns that has been add or an ERR_PTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				     struct dentry *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	struct aa_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	AA_BUG(!mutex_is_locked(&parent->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/* try and find the specified ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	/* released by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		ns = __aa_create_ns(parent, name, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		ns = ERR_PTR(-EEXIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	/* return ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	return ns;
^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_prepare_ns - find an existing or create a new namespace of @name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * @parent: ns to treat as parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  * @name: the namespace to find or add  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  * Returns: refcounted namespace or PTR_ERR if failed to create one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct aa_ns *aa_prepare_ns(struct aa_ns *parent, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	struct aa_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	mutex_lock_nested(&parent->lock, parent->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	/* try and find the specified ns and if it doesn't exist create it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	/* released by caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	ns = aa_get_ns(__aa_find_ns(&parent->sub_ns, name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		ns = __aa_create_ns(parent, name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	mutex_unlock(&parent->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	/* return ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static void __ns_list_release(struct list_head *head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * destroy_ns - remove everything contained by @ns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * @ns: namespace to have it contents removed  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static void destroy_ns(struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	mutex_lock_nested(&ns->lock, ns->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	/* release all profiles in this namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	__aa_profile_list_release(&ns->base.profiles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	/* release all sub namespaces */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	__ns_list_release(&ns->sub_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (ns->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		write_lock_irqsave(&ns->labels.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		__aa_proxy_redirect(ns_unconfined(ns),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 				    ns_unconfined(ns->parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		write_unlock_irqrestore(&ns->labels.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	__aafs_ns_rmdir(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	mutex_unlock(&ns->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * __aa_remove_ns - remove a namespace and all its children
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @ns: namespace to be removed  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * Requires: ns->parent->lock be held and ns removed from parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) void __aa_remove_ns(struct aa_ns *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	/* remove ns from namespace list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	list_del_rcu(&ns->base.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	destroy_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * __ns_list_release - remove all profile namespaces on the list put refs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  * @head: list of profile namespaces  (NOT NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  * Requires: namespace lock be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void __ns_list_release(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	struct aa_ns *ns, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	list_for_each_entry_safe(ns, tmp, head, base.list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		__aa_remove_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * aa_alloc_root_ns - allocate the root profile namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  * Returns: %0 on success else error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int __init aa_alloc_root_ns(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	/* released by aa_free_root_ns - used as list ref*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	root_ns = alloc_ns(NULL, "root");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	if (!root_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)   * aa_free_root_ns - free the root profile namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) void __init aa_free_root_ns(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	 struct aa_ns *ns = root_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	 root_ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	 destroy_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	 aa_put_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }