Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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_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 dentry *dir);
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));
}

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 */
+6 −4
Original line number Diff line number Diff line
@@ -566,7 +566,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,

	name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
	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)
			return NULL;
	} 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_profile *profile = NULL;
	const char *name = fqname, *info = NULL;
	char *ns_name = NULL;
	const char *ns_name = NULL;
	ssize_t error = 0;

	if (*fqname == 0) {
@@ -1120,9 +1120,11 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
	root = view;

	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 */
		ns = aa_find_ns(root, ns_name);
		ns = aa_lookupn_ns(root, ns_name, ns_len);
		if (!ns) {
			info = "namespace does not exist";
			error = -ENOENT;
+54 −0
Original line number Diff line number Diff line
@@ -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));
}

/**
 * __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,
				    struct dentry *dir)
{