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

Commit fe6bb31f authored by John Johansen's avatar John Johansen
Browse files

apparmor: split out shared policy_XXX fns to lib

parent 12557dcb
Loading
Loading
Loading
Loading
+81 −0
Original line number Original line Diff line number Diff line
@@ -91,4 +91,85 @@ static inline bool mediated_filesystem(struct dentry *dentry)
	return !(dentry->d_sb->s_flags & MS_NOUSER);
	return !(dentry->d_sb->s_flags & MS_NOUSER);
}
}


/* struct aa_policy - common part of both namespaces and profiles
 * @name: name of the object
 * @hname - The hierarchical name
 * @list: list policy object is on
 * @profiles: head of the profiles list contained in the object
 */
struct aa_policy {
	char *name;
	char *hname;
	struct list_head list;
	struct list_head profiles;
};

/**
 * hname_tail - find the last component of an hname
 * @name: hname to find the base profile name component of  (NOT NULL)
 *
 * Returns: the tail (base profile name) name component of an hname
 */
static inline const char *hname_tail(const char *hname)
{
	char *split;

	hname = strim((char *)hname);
	for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
		hname = split + 2;

	return hname;
}

/**
 * __policy_find - find a policy by @name on a policy list
 * @head: list to search  (NOT NULL)
 * @name: name to search for  (NOT NULL)
 *
 * Requires: rcu_read_lock be held
 *
 * Returns: unrefcounted policy that match @name or NULL if not found
 */
static inline struct aa_policy *__policy_find(struct list_head *head,
					      const char *name)
{
	struct aa_policy *policy;

	list_for_each_entry_rcu(policy, head, list) {
		if (!strcmp(policy->name, name))
			return policy;
	}
	return NULL;
}

/**
 * __policy_strn_find - find a policy that's name matches @len chars of @str
 * @head: list to search  (NOT NULL)
 * @str: string to search for  (NOT NULL)
 * @len: length of match required
 *
 * Requires: rcu_read_lock be held
 *
 * Returns: unrefcounted policy that match @str or NULL if not found
 *
 * if @len == strlen(@strlen) then this is equiv to __policy_find
 * other wise it allows searching for policy by a partial match of name
 */
static inline struct aa_policy *__policy_strn_find(struct list_head *head,
					    const char *str, int len)
{
	struct aa_policy *policy;

	list_for_each_entry_rcu(policy, head, list) {
		if (aa_strneq(policy->name, str, len))
			return policy;
	}

	return NULL;
}

bool aa_policy_init(struct aa_policy *policy, const char *prefix,
		    const char *name);
void aa_policy_destroy(struct aa_policy *policy);

#endif /* AA_LIB_H */
#endif /* AA_LIB_H */
+0 −13
Original line number Original line Diff line number Diff line
@@ -77,19 +77,6 @@ enum profile_flags {


struct aa_profile;
struct aa_profile;


/* struct aa_policy - common part of both namespaces and profiles
 * @name: name of the object
 * @hname - The hierarchical name
 * @list: list policy object is on
 * @profiles: head of the profiles list contained in the object
 */
struct aa_policy {
	char *name;
	char *hname;
	struct list_head list;
	struct list_head profiles;
};

/* struct aa_ns_acct - accounting of profiles in namespace
/* struct aa_ns_acct - accounting of profiles in namespace
 * @max_size: maximum space allowed for all profiles in namespace
 * @max_size: maximum space allowed for all profiles in namespace
 * @max_count: maximum number of profiles that can be in this namespace
 * @max_count: maximum number of profiles that can be in this namespace
+52 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include "include/audit.h"
#include "include/audit.h"
#include "include/apparmor.h"
#include "include/apparmor.h"
#include "include/lib.h"
#include "include/lib.h"
#include "include/policy.h"


/**
/**
 * aa_split_fqname - split a fqname into a profile and namespace name
 * aa_split_fqname - split a fqname into a profile and namespace name
@@ -105,3 +106,54 @@ void *__aa_kvmalloc(size_t size, gfp_t flags)
	}
	}
	return buffer;
	return buffer;
}
}

/**
 * aa_policy_init - initialize a policy structure
 * @policy: policy to initialize  (NOT NULL)
 * @prefix: prefix name if any is required.  (MAYBE NULL)
 * @name: name of the policy, init will make a copy of it  (NOT NULL)
 *
 * Note: this fn creates a copy of strings passed in
 *
 * Returns: true if policy init successful
 */
bool aa_policy_init(struct aa_policy *policy, const char *prefix,
		    const char *name)
{
	/* freed by policy_free */
	if (prefix) {
		policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
					GFP_KERNEL);
		if (policy->hname)
			sprintf(policy->hname, "%s//%s", prefix, name);
	} else
		policy->hname = kstrdup(name, GFP_KERNEL);
	if (!policy->hname)
		return 0;
	/* base.name is a substring of fqname */
	policy->name = (char *)hname_tail(policy->hname);
	INIT_LIST_HEAD(&policy->list);
	INIT_LIST_HEAD(&policy->profiles);

	return 1;
}

/**
 * aa_policy_destroy - free the elements referenced by @policy
 * @policy: policy that is to have its elements freed  (NOT NULL)
 */
void aa_policy_destroy(struct aa_policy *policy)
{
	/* still contains profiles -- invalid */
	if (on_list_rcu(&policy->profiles)) {
		AA_ERROR("%s: internal error, policy '%s' contains profiles\n",
			 __func__, policy->name);
	}
	if (on_list_rcu(&policy->list)) {
		AA_ERROR("%s: internal error, policy '%s' still on list\n",
			 __func__, policy->name);
	}

	/* don't free name as its a subset of hname */
	kzfree(policy->hname);
}
+4 −119
Original line number Original line Diff line number Diff line
@@ -99,121 +99,6 @@ const char *const aa_profile_mode_names[] = {
	"unconfined",
	"unconfined",
};
};


/**
 * hname_tail - find the last component of an hname
 * @name: hname to find the base profile name component of  (NOT NULL)
 *
 * Returns: the tail (base profile name) name component of an hname
 */
static const char *hname_tail(const char *hname)
{
	char *split;
	hname = strim((char *)hname);
	for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
		hname = split + 2;

	return hname;
}

/**
 * policy_init - initialize a policy structure
 * @policy: policy to initialize  (NOT NULL)
 * @prefix: prefix name if any is required.  (MAYBE NULL)
 * @name: name of the policy, init will make a copy of it  (NOT NULL)
 *
 * Note: this fn creates a copy of strings passed in
 *
 * Returns: true if policy init successful
 */
static bool policy_init(struct aa_policy *policy, const char *prefix,
			const char *name)
{
	/* freed by policy_free */
	if (prefix) {
		policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
					GFP_KERNEL);
		if (policy->hname)
			sprintf(policy->hname, "%s//%s", prefix, name);
	} else
		policy->hname = kstrdup(name, GFP_KERNEL);
	if (!policy->hname)
		return 0;
	/* base.name is a substring of fqname */
	policy->name = (char *)hname_tail(policy->hname);
	INIT_LIST_HEAD(&policy->list);
	INIT_LIST_HEAD(&policy->profiles);

	return 1;
}

/**
 * policy_destroy - free the elements referenced by @policy
 * @policy: policy that is to have its elements freed  (NOT NULL)
 */
static void policy_destroy(struct aa_policy *policy)
{
	/* still contains profiles -- invalid */
	if (on_list_rcu(&policy->profiles)) {
		AA_ERROR("%s: internal error, "
			 "policy '%s' still contains profiles\n",
			 __func__, policy->name);
		BUG();
	}
	if (on_list_rcu(&policy->list)) {
		AA_ERROR("%s: internal error, policy '%s' still on list\n",
			 __func__, policy->name);
		BUG();
	}

	/* don't free name as its a subset of hname */
	kzfree(policy->hname);
}

/**
 * __policy_find - find a policy by @name on a policy list
 * @head: list to search  (NOT NULL)
 * @name: name to search for  (NOT NULL)
 *
 * Requires: rcu_read_lock be held
 *
 * Returns: unrefcounted policy that match @name or NULL if not found
 */
static struct aa_policy *__policy_find(struct list_head *head, const char *name)
{
	struct aa_policy *policy;

	list_for_each_entry_rcu(policy, head, list) {
		if (!strcmp(policy->name, name))
			return policy;
	}
	return NULL;
}

/**
 * __policy_strn_find - find a policy that's name matches @len chars of @str
 * @head: list to search  (NOT NULL)
 * @str: string to search for  (NOT NULL)
 * @len: length of match required
 *
 * Requires: rcu_read_lock be held
 *
 * Returns: unrefcounted policy that match @str or NULL if not found
 *
 * if @len == strlen(@strlen) then this is equiv to __policy_find
 * other wise it allows searching for policy by a partial match of name
 */
static struct aa_policy *__policy_strn_find(struct list_head *head,
					    const char *str, int len)
{
	struct aa_policy *policy;

	list_for_each_entry_rcu(policy, head, list) {
		if (aa_strneq(policy->name, str, len))
			return policy;
	}

	return NULL;
}


/*
/*
 * Routines for AppArmor namespaces
 * Routines for AppArmor namespaces
@@ -280,7 +165,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
	AA_DEBUG("%s(%p)\n", __func__, ns);
	AA_DEBUG("%s(%p)\n", __func__, ns);
	if (!ns)
	if (!ns)
		return NULL;
		return NULL;
	if (!policy_init(&ns->base, prefix, name))
	if (!aa_policy_init(&ns->base, prefix, name))
		goto fail_ns;
		goto fail_ns;


	INIT_LIST_HEAD(&ns->sub_ns);
	INIT_LIST_HEAD(&ns->sub_ns);
@@ -321,7 +206,7 @@ static void free_namespace(struct aa_namespace *ns)
	if (!ns)
	if (!ns)
		return;
		return;


	policy_destroy(&ns->base);
	aa_policy_destroy(&ns->base);
	aa_put_namespace(ns->parent);
	aa_put_namespace(ns->parent);


	ns->unconfined->ns = NULL;
	ns->unconfined->ns = NULL;
@@ -595,7 +480,7 @@ void aa_free_profile(struct aa_profile *profile)
		return;
		return;


	/* free children profiles */
	/* free children profiles */
	policy_destroy(&profile->base);
	aa_policy_destroy(&profile->base);
	aa_put_profile(rcu_access_pointer(profile->parent));
	aa_put_profile(rcu_access_pointer(profile->parent));


	aa_put_namespace(profile->ns);
	aa_put_namespace(profile->ns);
@@ -657,7 +542,7 @@ struct aa_profile *aa_alloc_profile(const char *hname)
		goto fail;
		goto fail;
	kref_init(&profile->replacedby->count);
	kref_init(&profile->replacedby->count);


	if (!policy_init(&profile->base, NULL, hname))
	if (!aa_policy_init(&profile->base, NULL, hname))
		goto fail;
		goto fail;
	kref_init(&profile->count);
	kref_init(&profile->count);