Commit 3664268f authored by John Johansen's avatar John Johansen

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: default avatarJohn Johansen <john.johansen@canonical.com>
parent ae3b3165
...@@ -89,6 +89,8 @@ void aa_free_ns_kref(struct kref *kref); ...@@ -89,6 +89,8 @@ void aa_free_ns_kref(struct kref *kref);
struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name); struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n); struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n);
struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n);
struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name, struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name,
struct dentry *dir); struct dentry *dir);
struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name); struct 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,4 +150,15 @@ static inline struct aa_ns *__aa_find_ns(struct list_head *head,
return __aa_findn_ns(head, name, strlen(name)); return __aa_findn_ns(head, name, strlen(name));
} }
static inline struct aa_ns *__aa_lookup_ns(struct aa_ns *base,
const char *hname)
{
return __aa_lookupn_ns(base, hname, strlen(hname));
}
static inline struct aa_ns *aa_lookup_ns(struct aa_ns *view, const char *name)
{
return aa_lookupn_ns(view, name, strlen(name));
}
#endif /* AA_NAMESPACE_H */ #endif /* AA_NAMESPACE_H */
...@@ -566,7 +566,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base, ...@@ -566,7 +566,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len); name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
if (ns_name) { if (ns_name) {
ns = aa_findn_ns(base->ns, ns_name, ns_len); ns = aa_lookupn_ns(base->ns, ns_name, ns_len);
if (!ns) if (!ns)
return NULL; return NULL;
} else } else
...@@ -1108,7 +1108,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, ...@@ -1108,7 +1108,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
struct aa_ns *root = NULL, *ns = NULL; struct aa_ns *root = NULL, *ns = NULL;
struct aa_profile *profile = NULL; struct aa_profile *profile = NULL;
const char *name = fqname, *info = NULL; const char *name = fqname, *info = NULL;
char *ns_name = NULL; const char *ns_name = NULL;
ssize_t error = 0; ssize_t error = 0;
if (*fqname == 0) { if (*fqname == 0) {
...@@ -1120,9 +1120,11 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, ...@@ -1120,9 +1120,11 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
root = view; root = view;
if (fqname[0] == ':') { if (fqname[0] == ':') {
name = aa_split_fqname(fqname, &ns_name); size_t ns_len;
name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
/* released below */ /* released below */
ns = aa_find_ns(root, ns_name); ns = aa_lookupn_ns(root, ns_name, ns_len);
if (!ns) { if (!ns) {
info = "namespace does not exist"; info = "namespace does not exist";
error = -ENOENT; error = -ENOENT;
......
...@@ -183,6 +183,60 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name) ...@@ -183,6 +183,60 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
return aa_findn_ns(root, name, strlen(name)); return aa_findn_ns(root, name, strlen(name));
} }
/**
* __aa_lookupn_ns - lookup the namespace matching @hname
* @base: base list to start looking up profile name from (NOT NULL)
* @hname: hierarchical ns name (NOT NULL)
* @n: length of @hname
*
* Requires: rcu_read_lock be held
*
* Returns: unrefcounted ns pointer or NULL if not found
*
* Do a relative name lookup, recursing through profile tree.
*/
struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n)
{
struct aa_ns *ns = view;
const char *split;
for (split = strnstr(hname, "//", n); split;
split = strnstr(hname, "//", n)) {
ns = __aa_findn_ns(&ns->sub_ns, hname, split - hname);
if (!ns)
return NULL;
n -= split + 2 - hname;
hname = split + 2;
}
if (n)
return __aa_findn_ns(&ns->sub_ns, hname, n);
return NULL;
}
/**
* aa_lookupn_ns - look up a policy namespace relative to @view
* @view: namespace to search in (NOT NULL)
* @name: name of namespace to find (NOT NULL)
* @n: length of @name
*
* Returns: a refcounted namespace on the list, or NULL if no namespace
* called @name exists.
*
* refcount released by caller
*/
struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n)
{
struct aa_ns *ns = NULL;
rcu_read_lock();
ns = aa_get_ns(__aa_lookupn_ns(view, name, n));
rcu_read_unlock();
return ns;
}
static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name, static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
struct dentry *dir) struct dentry *dir)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment