[apparmor] [RFC PATCH 1/1] libapparmor: Create man page for aa_stack_profile()/aa_stack_onexec()

John Johansen john.johansen at canonical.com
Wed Jan 13 09:26:21 UTC 2016


On 01/12/2016 10:40 PM, John Johansen wrote:
> On 01/12/2016 10:10 PM, Tyler Hicks wrote:
>> Thanks, John - I hadn't given a lot of thought to the policy changes
>> required and this email was very helpful.
>>
>> On 2016-01-12 15:10:28, John Johansen wrote:
>>> On 01/11/2016 06:27 PM, Seth Arnold wrote:
>>>> On Mon, Jan 11, 2016 at 05:41:43PM -0800, John Johansen wrote:
> 
> <<snip>>
> 
>>> now lets look at the stack on exec case. The stack addition is delayed
>>> until exec.  The current profile will have the stack added on top, the
>>> question is when and how.
>>>
>>> 1. stack_onexec as stack + change_onexec: stack is computed immediately
>>>     but the transition is delayed until exec (this overrides any
>>>     transitions and is how Tyler described it)
>>>   A -- stack_onexec B -- exec --> A//&B
>>
>> Yes, this is what I pictured when a program, confined by "A", calls
>> aa_stack_onexec("B").
>>
>>>
>>> 2. stack_onexec, stack delayed until exec applied pre-exec transitions
>>>   A -- stack_onexec B -- exec apply stack -- A//&B -- exec trans --> C//&D
>>
>> I can't imagine much use for this flow. Unless there's a good use case,
>> I think we should throw it out.
>>
>>>
>>> 3. stack_onexec, stack delayed until exec applied post-exec transitions
>>>   A -- stack_onexec B -- exec trans -- C -- apply stack --> C//&B
>>
>> I was actually thinking that this would happen when a program, confined
>> by "A", calls aa_change_onexec("C//&B"). It is changing to a specific
>> stack of profiles on exec instead of stacking an additional profile on
>> top of its current confinement.
>>
> It does. However there is a difference between an exec specified in
> policy and a change directed by the application. This plays into
> the exec transitions that use globbing
> 
>>> each is a viable definition and each could have their uses.
>>>
>>> Example 1: is like change_onexec in that it completely replaces the
>>> domain transition, with a profile set computed at the time it is called.
>>> Neither A nor B require a domain transition, A requires a change_profile
>>> or stack_profile rule, and all intermediary permissions between
>>> stack_onexec and exec need to be included in B
>>>
>>> This is the most like change_onexec in behavior. However a better
>>> description of it is stack and apply at exec.
>>>
>>> Example 2: follows what happens with aa_stack, contrary to change_onexec
>>>   mimics what happens with straight stacking, and like change_onexec
>>>   puts all intermediary permissions between stack_onexec and exec into A.
>>>   However A//&B must have exec permissions and this is contrary to how
>>>   change_onexec works. That is change_onexec has a rule in A that defines
>>>   the exec permission and has priority over regular domain transition
>>>   rules and the target B does NOT need an exec rule.
>>>
>>>   We could and should have a stack_onexec or use the change_onexec rule to
>>>   mitigate the first difference but that B requires and exec rule is odd,
>>>   and I don't think it is a viable definition.
>>>
>>> Example 3: is similar to example 2 except B does not require a domain
>>>   transition. It can be thought of stack on top of what ever current is
>>>   after exec.
>>>
>>>   Rules wouldn't be required in this model but still might be desirable.
>>>
>>> Whether to go with 1, 3 or both depends on use cases, and how these are
>>> implemented. So lets look at the exec side some more. Because exec rules
>>> are also going to pickup the ability to specify stacking. Note the syntax
>>> here is not final but sufficient for the discussion.
>>>
>>> exec rules allow naming a profile to transition to
>>>   px /foo/bar -> A,
>>>   px /** -> A,
>>>
>>> this will be extended to support specifying an explicit stack
>>>   px /foo/bar -> A//&B,
>>>   px /** -> A//&B,
>>>
>>> however we may want to be able to specify the stack based off the target
>>> profile, this works for
>>>   px /foo/bar -> /foo/bar//&B,
>>>
>>> but does not work for the rule with globbing because there can be
>>> multiple targets matched.
>>>   px /** -> ??//&B,
>>>
>>> we can get around this by either introducing a special variable
>>>   px /** -> @{TARGET}//&B,
>>
>> This feels like we're bending over backwards to appease the lazy policy
>> author. He/She already has to define the profiles for each one of those
>> targets so why not make him/her include a transition rule for each
>> target?
>>
> Yes and no.
> 
> Globbing, pix, and pux transitions are all used to support lazy policy.
> Or another way of putting it is incremental policy. If we require that
> all possible targets have profiles defined and that all profiles exist
> in a set at author ship and at compile time, we can drop domain globbing,
> pix, and pux transitions. As well as being able to specify the target.
> 
> The compile time requirement:
>   means no incremental policy load, policy must be compiled and loaded
>   as a set. Replacing a single profile means that all profiles must be
>   updated. At the very least if any single profile as a relation that
>   changes everyone that could be involved must be loaded in the set.
> 
>   I am not against doing this. It has several advantages in that static
>   compile time checks can be done and many optimizations. However this
>   is not possible at this time. It will be a lot of work, and currently
>   too many things rely on incremental replacement.
> 
> The time of author ship requirement:
>   All these possible relations must be resolved before policy will
>   compile. If any profile is added that setups a new relation other
>   profiles need to be updated as well.
> 
>   There are ways to deal with this via includes etc, but globbing,
>   pix, and pux rules also are a means of solving this, even under
>   the compile time requirement, as the compile can expand and
>   resolve these.
> 
>   I can assure you that we will need ways to ease update of profile
>   relations whether we stay with the current incremental compile and
>   load or whether move to a single atomic compile and load.
> 
also globbing isn't just a way to handle incremental policy, it is
also an efficient way to specify patterns that should exist and shrink
policy size.




More information about the AppArmor mailing list