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

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

apparmor: share profile name on replacement



The profile names are the same, leverage this.

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent cf797c0e
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -100,6 +100,36 @@ static inline bool path_mediated_fs(struct dentry *dentry)
	return !(dentry->d_sb->s_flags & MS_NOUSER);
}


struct counted_str {
	struct kref count;
	char name[];
};

#define str_to_counted(str) \
	((struct counted_str *)(str - offsetof(struct counted_str, name)))

#define __counted	/* atm just a notation */

void aa_str_kref(struct kref *kref);
char *aa_str_alloc(int size, gfp_t gfp);


static inline __counted char *aa_get_str(__counted char *str)
{
	if (str)
		kref_get(&(str_to_counted(str)->count));

	return str;
}

static inline void aa_put_str(__counted char *str)
{
	if (str)
		kref_put(&str_to_counted(str)->count, aa_str_kref);
}


/* struct aa_policy - common part of both namespaces and profiles
 * @name: name of the object
 * @hname - The hierarchical name
@@ -108,7 +138,7 @@ static inline bool path_mediated_fs(struct dentry *dentry)
 */
struct aa_policy {
	const char *name;
	const char *hname;
	__counted char *hname;
	struct list_head list;
	struct list_head profiles;
};
+32 −8
Original line number Diff line number Diff line
@@ -134,6 +134,24 @@ void aa_info_message(const char *str)
	printk(KERN_INFO "AppArmor: %s\n", str);
}

__counted char *aa_str_alloc(int size, gfp_t gfp)
{
	struct counted_str *str;

	str = kmalloc(sizeof(struct counted_str) + size, gfp);
	if (!str)
		return NULL;

	kref_init(&str->count);
	return str->name;
}

void aa_str_kref(struct kref *kref)
{
	kfree(container_of(kref, struct counted_str, count));
}


const char aa_file_perm_chrs[] = "xwracd         km l     ";
const char *aa_file_perm_names[] = {
	"exec",
@@ -296,6 +314,7 @@ void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
 * @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)
 * @gfp: allocation mode
 *
 * Note: this fn creates a copy of strings passed in
 *
@@ -304,16 +323,21 @@ void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
bool aa_policy_init(struct aa_policy *policy, const char *prefix,
		    const char *name, gfp_t gfp)
{
	char *hname;

	/* freed by policy_free */
	if (prefix) {
		policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
					gfp);
		if (policy->hname)
			sprintf((char *)policy->hname, "%s//%s", prefix, name);
	} else
		policy->hname = kstrdup(name, gfp);
	if (!policy->hname)
		hname = aa_str_alloc(strlen(prefix) + strlen(name) + 3, gfp);
		if (hname)
			sprintf(hname, "%s//%s", prefix, name);
	} else {
		hname = aa_str_alloc(strlen(name) + 1, gfp);
		if (hname)
			strcpy(hname, name);
	}
	if (!hname)
		return false;
	policy->hname = hname;
	/* base.name is a substring of fqname */
	policy->name = basename(policy->hname);
	INIT_LIST_HEAD(&policy->list);
@@ -332,5 +356,5 @@ void aa_policy_destroy(struct aa_policy *policy)
	AA_BUG(on_list_rcu(&policy->list));

	/* don't free name as its a subset of hname */
	kzfree(policy->hname);
	aa_put_str(policy->hname);
}
+9 −0
Original line number Diff line number Diff line
@@ -829,6 +829,14 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
	return 0;
}

static void share_name(struct aa_profile *old, struct aa_profile *new)
{
	aa_put_str(new->base.hname);
	aa_get_str(old->base.hname);
	new->base.hname = old->base.hname;
	new->base.name = old->base.name;
}

/**
 * aa_replace_profiles - replace profile(s) on the profile list
 * @policy_ns: namespace load is occurring on
@@ -1013,6 +1021,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
			     NULL, error);

		if (ent->old) {
			share_name(ent->old, ent->new);
			__replace_profile(ent->old, ent->new, 1);
			if (ent->rename) {
				/* aafs interface uses proxy */