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>
This commit is contained in:
parent
ae3b316536
commit
3664268f19
3 changed files with 73 additions and 4 deletions
|
@ -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,
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue