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

Commit 435222bc authored by John Johansen's avatar John Johansen
Browse files

apparmor: refactor updating profiles to the newest parent

parent a1bd627b
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -837,6 +837,27 @@ static void share_name(struct aa_profile *old, struct aa_profile *new)
	new->base.name = old->base.name;
}

/* Update to newest version of parent after previous replacements
 * Returns: unrefcount newest version of parent
 */
static struct aa_profile *update_to_newest_parent(struct aa_profile *new)
{
	struct aa_profile *parent, *newest;

	parent = rcu_dereference_protected(new->parent,
					   mutex_is_locked(&new->ns->lock));
	newest = aa_get_newest_profile(parent);

	/* parent replaced in this atomic set? */
	if (newest != parent) {
		aa_put_profile(parent);
		rcu_assign_pointer(new->parent, newest);
	} else
		aa_put_profile(newest);

	return newest;
}

/**
 * aa_replace_profiles - replace profile(s) on the profile list
 * @policy_ns: namespace load is occurring on
@@ -1052,10 +1073,16 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
			__list_add_profile(&newest->base.profiles, ent->new);
			aa_put_profile(newest);
		} else {
			/* aafs interface uses proxy */
			rcu_assign_pointer(ent->new->proxy->profile,
					   aa_get_profile(ent->new));
			__list_add_profile(&ns->base.profiles, ent->new);
			struct list_head *lh;

			if (rcu_access_pointer(ent->new->parent)) {
				struct aa_profile *parent;

				parent = update_to_newest_parent(ent->new);
				lh = &parent->base.profiles;
			} else
				lh = &ns->base.profiles;
			__list_add_profile(lh, ent->new);
		}
	skip:
		aa_load_ent_free(ent);