aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-06-02 20:44:27 -0400
committerJohn Johansen <john.johansen@canonical.com>2017-06-10 20:11:32 -0400
commit3664268f19ea07bec55df92fe53ff9ed28968bcc (patch)
tree3db852e790109e4fbf27e7f91c6e0e642371c927
parentae3b31653691b9c5b572b99596de3dfcc8f05006 (diff)
apparmor: add namespace lookup fns()
Currently lookups are restricted to a single ns component in the path. However when namespaces are allowed to have separate views, and scopes this will not be sufficient, as it will be possible to have a multiple component ns path in scope. Add some ns lookup fns() to allow this and use them. Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r--security/apparmor/include/policy_ns.h13
-rw-r--r--security/apparmor/policy.c10
-rw-r--r--security/apparmor/policy_ns.c54
3 files changed, 73 insertions, 4 deletions
diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
index 23e7cb770226..2f7e480a34e0 100644
--- a/security/apparmor/include/policy_ns.h
+++ b/security/apparmor/include/policy_ns.h
@@ -89,6 +89,8 @@ void aa_free_ns_kref(struct kref *kref);
89 89
90struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name); 90struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
91struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n); 91struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
92struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n);
93struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n);
92struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name, 94struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name,
93 struct dentry *dir); 95 struct dentry *dir);
94struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name); 96struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name);
@@ -148,4 +150,15 @@ static inline struct aa_ns *__aa_find_ns(struct list_head *head,
148 return __aa_findn_ns(head, name, strlen(name)); 150 return __aa_findn_ns(head, name, strlen(name));
149} 151}
150 152
153static inline struct aa_ns *__aa_lookup_ns(struct aa_ns *base,
154 const char *hname)
155{
156 return __aa_lookupn_ns(base, hname, strlen(hname));
157}
158
159static inline struct aa_ns *aa_lookup_ns(struct aa_ns *view, const char *name)
160{
161 return aa_lookupn_ns(view, name, strlen(name));
162}
163
151#endif /* AA_NAMESPACE_H */ 164#endif /* AA_NAMESPACE_H */
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 0a99e5324da0..d95aae6bf710 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -566,7 +566,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
566 566
567 name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len); 567 name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
568 if (ns_name) { 568 if (ns_name) {
569 ns = aa_findn_ns(base->ns, ns_name, ns_len); 569 ns = aa_lookupn_ns(base->ns, ns_name, ns_len);
570 if (!ns) 570 if (!ns)
571 return NULL; 571 return NULL;
572 } else 572 } else
@@ -1108,7 +1108,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
1108 struct aa_ns *root = NULL, *ns = NULL; 1108 struct aa_ns *root = NULL, *ns = NULL;
1109 struct aa_profile *profile = NULL; 1109 struct aa_profile *profile = NULL;
1110 const char *name = fqname, *info = NULL; 1110 const char *name = fqname, *info = NULL;
1111 char *ns_name = NULL; 1111 const char *ns_name = NULL;
1112 ssize_t error = 0; 1112 ssize_t error = 0;
1113 1113
1114 if (*fqname == 0) { 1114 if (*fqname == 0) {
@@ -1120,9 +1120,11 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
1120 root = view; 1120 root = view;
1121 1121
1122 if (fqname[0] == ':') { 1122 if (fqname[0] == ':') {
1123 name = aa_split_fqname(fqname, &ns_name); 1123 size_t ns_len;
1124
1125 name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
1124 /* released below */ 1126 /* released below */
1125 ns = aa_find_ns(root, ns_name); 1127 ns = aa_lookupn_ns(root, ns_name, ns_len);
1126 if (!ns) { 1128 if (!ns) {
1127 info = "namespace does not exist"; 1129 info = "namespace does not exist";
1128 error = -ENOENT; 1130 error = -ENOENT;
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index f3418a9e59b1..c05316809a5e 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -183,6 +183,60 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
183 return aa_findn_ns(root, name, strlen(name)); 183 return aa_findn_ns(root, name, strlen(name));
184} 184}
185 185
186/**
187 * __aa_lookupn_ns - lookup the namespace matching @hname
188 * @base: base list to start looking up profile name from (NOT NULL)
189 * @hname: hierarchical ns name (NOT NULL)
190 * @n: length of @hname
191 *
192 * Requires: rcu_read_lock be held
193 *
194 * Returns: unrefcounted ns pointer or NULL if not found
195 *
196 * Do a relative name lookup, recursing through profile tree.
197 */
198struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n)
199{
200 struct aa_ns *ns = view;
201 const char *split;
202
203 for (split = strnstr(hname, "//", n); split;
204 split = strnstr(hname, "//", n)) {
205 ns = __aa_findn_ns(&ns->sub_ns, hname, split - hname);
206 if (!ns)
207 return NULL;
208
209 n -= split + 2 - hname;
210 hname = split + 2;
211 }
212
213 if (n)
214 return __aa_findn_ns(&ns->sub_ns, hname, n);
215 return NULL;
216}
217
218/**
219 * aa_lookupn_ns - look up a policy namespace relative to @view
220 * @view: namespace to search in (NOT NULL)
221 * @name: name of namespace to find (NOT NULL)
222 * @n: length of @name
223 *
224 * Returns: a refcounted namespace on the list, or NULL if no namespace
225 * called @name exists.
226 *
227 * refcount released by caller
228 */
229struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n)
230{
231 struct aa_ns *ns = NULL;
232
233 rcu_read_lock();
234 ns = aa_get_ns(__aa_lookupn_ns(view, name, n));
235 rcu_read_unlock();
236
237 return ns;
238}
239
186static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name, 240static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
187 struct dentry *dir) 241 struct dentry *dir)
188{ 242{