[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