1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * AppArmor security module |
4 | * |
5 | * This file contains AppArmor policy definitions. |
6 | * |
7 | * Copyright (C) 1998-2008 Novell/SUSE |
8 | * Copyright 2009-2017 Canonical Ltd. |
9 | */ |
10 | |
11 | #ifndef __AA_NAMESPACE_H |
12 | #define __AA_NAMESPACE_H |
13 | |
14 | #include <linux/kref.h> |
15 | |
16 | #include "apparmor.h" |
17 | #include "apparmorfs.h" |
18 | #include "label.h" |
19 | #include "policy.h" |
20 | |
21 | |
22 | /* struct aa_ns_acct - accounting of profiles in namespace |
23 | * @max_size: maximum space allowed for all profiles in namespace |
24 | * @max_count: maximum number of profiles that can be in this namespace |
25 | * @size: current size of profiles |
26 | * @count: current count of profiles (includes null profiles) |
27 | */ |
28 | struct aa_ns_acct { |
29 | int max_size; |
30 | int max_count; |
31 | int size; |
32 | int count; |
33 | }; |
34 | |
35 | /* struct aa_ns - namespace for a set of profiles |
36 | * @base: common policy |
37 | * @parent: parent of namespace |
38 | * @lock: lock for modifying the object |
39 | * @acct: accounting for the namespace |
40 | * @unconfined: special unconfined profile for the namespace |
41 | * @sub_ns: list of namespaces under the current namespace. |
42 | * @uniq_null: uniq value used for null learning profiles |
43 | * @uniq_id: a unique id count for the profiles in the namespace |
44 | * @level: level of ns within the tree hierarchy |
45 | * @dents: dentries for the namespaces file entries in apparmorfs |
46 | * |
47 | * An aa_ns defines the set profiles that are searched to determine which |
48 | * profile to attach to a task. Profiles can not be shared between aa_ns |
49 | * and profile names within a namespace are guaranteed to be unique. When |
50 | * profiles in separate namespaces have the same name they are NOT considered |
51 | * to be equivalent. |
52 | * |
53 | * Namespaces are hierarchical and only namespaces and profiles below the |
54 | * current namespace are visible. |
55 | * |
56 | * Namespace names must be unique and can not contain the characters :/\0 |
57 | */ |
58 | struct aa_ns { |
59 | struct aa_policy base; |
60 | struct aa_ns *parent; |
61 | struct mutex lock; |
62 | struct aa_ns_acct acct; |
63 | struct aa_profile *unconfined; |
64 | struct list_head sub_ns; |
65 | atomic_t uniq_null; |
66 | long uniq_id; |
67 | int level; |
68 | long revision; |
69 | wait_queue_head_t wait; |
70 | |
71 | struct aa_labelset labels; |
72 | struct list_head rawdata_list; |
73 | |
74 | struct dentry *dents[AAFS_NS_SIZEOF]; |
75 | }; |
76 | |
77 | extern struct aa_label *kernel_t; |
78 | extern struct aa_ns *root_ns; |
79 | |
80 | extern const char *aa_hidden_ns_name; |
81 | |
82 | #define ns_unconfined(NS) (&(NS)->unconfined->label) |
83 | |
84 | bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns); |
85 | const char *aa_ns_name(struct aa_ns *parent, struct aa_ns *child, bool subns); |
86 | void aa_free_ns(struct aa_ns *ns); |
87 | int aa_alloc_root_ns(void); |
88 | void aa_free_root_ns(void); |
89 | |
90 | struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n); |
91 | struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n); |
92 | struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name, |
93 | struct dentry *dir); |
94 | struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name); |
95 | void __aa_remove_ns(struct aa_ns *ns); |
96 | |
97 | static inline struct aa_profile *aa_deref_parent(struct aa_profile *p) |
98 | { |
99 | return rcu_dereference_protected(p->parent, |
100 | mutex_is_locked(&p->ns->lock)); |
101 | } |
102 | |
103 | /** |
104 | * aa_get_ns - increment references count on @ns |
105 | * @ns: namespace to increment reference count of (MAYBE NULL) |
106 | * |
107 | * Returns: pointer to @ns, if @ns is NULL returns NULL |
108 | * Requires: @ns must be held with valid refcount when called |
109 | */ |
110 | static inline struct aa_ns *aa_get_ns(struct aa_ns *ns) |
111 | { |
112 | if (ns) |
113 | aa_get_profile(p: ns->unconfined); |
114 | |
115 | return ns; |
116 | } |
117 | |
118 | /** |
119 | * aa_put_ns - decrement refcount on @ns |
120 | * @ns: namespace to put reference of |
121 | * |
122 | * Decrement reference count of @ns and if no longer in use free it |
123 | */ |
124 | static inline void aa_put_ns(struct aa_ns *ns) |
125 | { |
126 | if (ns) |
127 | aa_put_profile(p: ns->unconfined); |
128 | } |
129 | |
130 | /** |
131 | * __aa_findn_ns - find a namespace on a list by @name |
132 | * @head: list to search for namespace on (NOT NULL) |
133 | * @name: name of namespace to look for (NOT NULL) |
134 | * @n: length of @name |
135 | * Returns: unrefcounted namespace |
136 | * |
137 | * Requires: rcu_read_lock be held |
138 | */ |
139 | static inline struct aa_ns *__aa_findn_ns(struct list_head *head, |
140 | const char *name, size_t n) |
141 | { |
142 | return (struct aa_ns *)__policy_strn_find(head, str: name, len: n); |
143 | } |
144 | |
145 | static inline struct aa_ns *__aa_find_ns(struct list_head *head, |
146 | const char *name) |
147 | { |
148 | return __aa_findn_ns(head, name, strlen(name)); |
149 | } |
150 | |
151 | #endif /* AA_NAMESPACE_H */ |
152 | |