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

Commit 181f7c97 authored by John Johansen's avatar John Johansen
Browse files

apparmor: name null-XXX profiles after the executable



When possible its better to name a learning profile after the missing
profile in question. This allows for both more informative names and
for profile reuse.

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent 30b026a8
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -442,7 +442,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
		}
	} else if (COMPLAIN_MODE(profile)) {
		/* no exec permission - are we in learning mode */
		new_profile = aa_new_null_profile(profile, 0);
		new_profile = aa_new_null_profile(profile, false, name,
						  GFP_ATOMIC);
		if (!new_profile) {
			error = -ENOMEM;
			info = "could not create null profile";
@@ -667,7 +668,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
			aa_put_profile(root);
			target = name;
			/* released below */
			hat = aa_new_null_profile(profile, 1);
			hat = aa_new_null_profile(profile, true, hats[0],
						  GFP_KERNEL);
			if (!hat) {
				info = "failed null profile create";
				error = -ENOMEM;
@@ -815,7 +817,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
		if (permtest || !COMPLAIN_MODE(profile))
			goto audit;
		/* released below */
		target = aa_new_null_profile(profile, 0);
		target = aa_new_null_profile(profile, false, hname, GFP_KERNEL);
		if (!target) {
			info = "failed null profile create";
			error = -ENOMEM;
+2 −1
Original line number Diff line number Diff line
@@ -173,7 +173,8 @@ void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);

void aa_free_proxy_kref(struct kref *kref);
struct aa_profile *aa_alloc_profile(const char *name, gfp_t gfp);
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
				       const char *base, gfp_t gfp);
void aa_free_profile(struct aa_profile *profile);
void aa_free_profile_kref(struct kref *kref);
struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
+40 −13
Original line number Diff line number Diff line
@@ -288,12 +288,16 @@ struct aa_profile *aa_alloc_profile(const char *hname, gfp_t gfp)
}

/**
 * aa_new_null_profile - create a new null-X learning profile
 * aa_new_null_profile - create or find a null-X learning profile
 * @parent: profile that caused this profile to be created (NOT NULL)
 * @hat: true if the null- learning profile is a hat
 * @base: name to base the null profile off of
 * @gfp: type of allocation
 *
 * Create a null- complain mode profile used in learning mode.  The name of
 * the profile is unique and follows the format of parent//null-<uniq>.
 * Find/Create a null- complain mode profile used in learning mode.  The
 * name of the profile is unique and follows the format of parent//null-XXX.
 * where XXX is based on the @name or if that fails or is not supplied
 * a unique number
 *
 * null profiles are added to the profile list but the list does not
 * hold a count on them so that they are automatically released when
@@ -301,27 +305,45 @@ struct aa_profile *aa_alloc_profile(const char *hname, gfp_t gfp)
 *
 * Returns: new refcounted profile else NULL on failure
 */
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
				       const char *base, gfp_t gfp)
{
	struct aa_profile *profile = NULL;
	struct aa_profile *profile;
	char *name;
	int uniq = atomic_inc_return(&parent->ns->uniq_null);

	/* freed below */
	name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
	AA_BUG(!parent);

	if (base) {
		name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
			       gfp);
		if (name) {
			sprintf(name, "%s//null-%s", parent->base.hname, base);
			goto name;
		}
		/* fall through to try shorter uniq */
	}

	name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
	if (!name)
		goto fail;
	sprintf(name, "%s//null-%x", parent->base.hname, uniq);
		return NULL;
	sprintf(name, "%s//null-%x", parent->base.hname,
		atomic_inc_return(&parent->ns->uniq_null));

	profile = aa_alloc_profile(name, GFP_KERNEL);
	kfree(name);
name:
	/* lookup to see if this is a dup creation */
	profile = aa_find_child(parent, basename(name));
	if (profile)
		goto out;

	profile = aa_alloc_profile(name, gfp);
	if (!profile)
		goto fail;

	profile->mode = APPARMOR_COMPLAIN;
	profile->flags = PFLAG_NULL;
	profile->flags |= PFLAG_NULL;
	if (hat)
		profile->flags |= PFLAG_HAT;
	profile->path_flags = parent->path_flags;

	/* released on free_profile */
	rcu_assign_pointer(profile->parent, aa_get_profile(parent));
@@ -332,9 +354,14 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
	mutex_unlock(&profile->ns->lock);

	/* refcount released by caller */
out:
	kfree(name);

	return profile;

fail:
	kfree(name);
	aa_free_profile(profile);
	return NULL;
}