[apparmor] [PATCH 03/36] apparmor: change how profile replacement update is done
Seth Arnold
seth.arnold at canonical.com
Wed May 8 01:09:15 UTC 2013
On Wed, May 01, 2013 at 02:30:48PM -0700, John Johansen wrote:
> remove the use of replaced by chaining and move to profile invalidation
> and lookup to handle task replacement.
>
> Replacement chaining can result in large chains of profiles being pinned
> in memory when one profile in the chain is use. With implicit labeling
> this will be even more of a problem, so move to a direct lookup method.
Could you explain the old_replacedby in the following few chunks? I just
can't make heads or tails of why it works the way it does. Thanks.
> @@ -992,6 +995,7 @@ static struct aa_profile *__list_lookup_parent(struct list_head *lh,
> * __replace_profile - replace @old with @new on a list
> * @old: profile to be replaced (NOT NULL)
> * @new: profile to replace @old with (NOT NULL)
> + * @old_replacedby: transfer @old->replacedby to @new
> *
> * Will duplicate and refcount elements that @new inherits from @old
> * and will inherit @old children.
> @@ -1000,7 +1004,8 @@ static struct aa_profile *__list_lookup_parent(struct list_head *lh,
> *
> * Requires: namespace list lock be held, or list not be shared
> */
> -static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
> +static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
> + int old_replacedby)
> {
> struct aa_profile *child, *tmp;
>
> @@ -1015,7 +1020,7 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
> p = __find_child(&new->base.profiles, child->base.name);
> if (p) {
> /* @p replaces @child */
> - __replace_profile(child, p);
> + __replace_profile(child, p, old_replacedby);
> continue;
> }
>
> @@ -1034,8 +1039,11 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
> struct aa_profile *parent = rcu_dereference(old->parent);
> rcu_assign_pointer(new->parent, aa_get_profile(parent));
> }
> - /* released by free_profile */
> - old->replacedby = aa_get_profile(new);
> + __aa_update_replacedby(old, new);
> + if (old_replacedby) {
> + aa_put_replacedby(new->replacedby);
> + new->replacedby = aa_get_replacedby(old->replacedby);
> + }
>
> if (list_empty_rcu(&new->base.list)) {
> /* new is not on a list already */
> @@ -1159,23 +1167,24 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
> audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
>
> if (ent->old) {
> - __replace_profile(ent->old, ent->new);
> + __replace_profile(ent->old, ent->new, 1);
> if (ent->rename)
> - __replace_profile(ent->rename, ent->new);
> + __replace_profile(ent->rename, ent->new, 0);
> } else if (ent->rename) {
> - __replace_profile(ent->rename, ent->new);
> + __replace_profile(ent->rename, ent->new, 0);
> } else if (ent->new->parent) {
> struct aa_profile *parent, *newest;
> parent = rcu_dereference_protected(ent->new->parent,
> mutex_is_locked(&ns->lock));
> - newest = aa_newest_version(parent);
> + newest = aa_get_newest_profile(parent);
>
> /* parent replaced in this atomic set? */
> if (newest != parent) {
> aa_get_profile(newest);
> aa_put_profile(parent);
> rcu_assign_pointer(ent->new->parent, newest);
> - }
> + } else
> + aa_put_profile(newest);
> __list_add_profile(&parent->base.profiles, ent->new);
> } else
> __list_add_profile(&ns->base.profiles, ent->new);
> --
> 1.8.1.2
>
>
> --
> AppArmor mailing list
> AppArmor at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130507/29a2a6bf/attachment.pgp>
More information about the AppArmor
mailing list