[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