[apparmor] [RFC PATCH 1/1] libapparmor: Create man page for aa_stack_profile()/aa_stack_onexec()
Tyler Hicks
tyhicks at canonical.com
Wed Jan 13 06:10:16 UTC 2016
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:
> >>>> +Stacking another profile via aa_stack_profile() is permanent and the process is not
> >>>> +permitted to revert to the previous confinement context. Unlike
> >>>> +aa_change_profile(2), confined programs wanting to use aa_stack_profile() need
> >>>> +no special rules in their profile to stack a new profile since the operation
> >>>> +does not broaden the allowed permissions.
> >
> >>> I'm also afraid that this kind of rule might also allow these APIs to be
> >>> used by exploit code to unreasonably manipulate profile transitions in
> >>> ways that aren't expected by policy authors.
> >>>
> >> how so?
> >>
> >> the policy will have to allow stacking, and stacking is purely restrictive.
> >> If the profile allows the stack, then and only then can it take priority
> >> over the profiles exec transitions, just like with change_profile.
> >
> > Earlier in the manpage it was suggested that policy does _not_ have to
> > have syntax to allow stacking.
> >
> > If the stacking is entirely under the control of the program and not
> > influenced by policy (as suggested in this manpage) then the following
> > attack is feasible:
> >
> > Presume we're running in a confined sshd-alike application. The profile
> > for the sshd-alike includes the following rule:
> >
> > /bin/bash Px -> user_shell,
> >
> > The intention is that users are confined to a specific profile once they
> > are authenticated, one that doesn't allow system administration tasks.
> >
> > If an exploit during user authentication is allowed to call
> > aa_stack_onexec("administrator_shell");
> > and this API call overrides the Px in the profile, then an exploit could
> > bypass the restricted profile and get a profile that allows administration
> > tasks.
> >
> not necessarily so. There are in fact 3 different semantics stack_onexec
> could take on, and we will have to be precise about what it is doing and
> why.
>
> The desire to delay the stack to exec is similar to change_onexec so that
> you don't have to implement a stub profile in policy for the brief period
> between change_profile and the exec.
>
> Eg.
>
> basic change_profile: replaces the current profile immediately
> A -- change_profile --> B
>
> change_onexec: replaces the current profile, but delays it until exec
> A -- change_onexec ... exec --> B
>
> this avoids having to make policy where what you do is
> A -- change_profile --> STUB
> STUB --> exec --> B
>
> where STUB has to have permissions for intermediate operation and then
> the exec transition.
>
> With change_profile you could skip the STUB profile portion and include
> any permissions granted in STUB into the B profile. However since
> change_profile is usually being used to reduce permissions, that is not
> desirable, where change_onexec includes the STUB profile permissions
> into A.
>
> Now lets move on to stacking.
>
> basic stack: reduce the current permissions immediately
> A -- stack B --> A//&B
>
> notice how A wasn't replaced or removed. Once we come to the exec
> the exec rules for both A and B are applied. Lets say A transitions
> to C and B to D then we get
> A -- stack B --> A//&B -- exec --> C//&D
>
> if however A and B both transition to C then we get
> A -- stack B --> A//&B -- exec --> C//&C -- collapses to --> C
Interesting stuff. Now I know what you mean when you say, "The stack
collapses".
> 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.
> 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?
> or extending the stacking syntax a little to mean use the target and
> what is specified.
> px /** -> &B, # leading & specifies use target and stack B
>
> however neither of these syntaxes are sufficient (for globbing rules) to
> specify the final confinement when we want the execed process to have
> current confinement and B. We can extend each syntax to support this.
>
> px /** -> @{SELF}//&B,
> #Note: @{PROFILE} is not correct as the task may already have
> # a stack of profiles, so it is current confinement
>
> and
> ix /** -> &B, # notice ix instead of px
>
>
> notice how the choices 1 and 3 for stack_onexc parallel the above exec
> rules.
> 1. is the same as
> px /** -> @{SELF}//&B,
> or
> ix /** -> &B,
>
> 3. is the same as
> px /** -> @{TARGET}//&B,
> or
> px /** -> &B,
>
> both cases have their uses, and I believe we need to support both. So
> the stack api should probably support both as well.
I already mentioned this above but I think the stack API does, as
proposed, if aa_change_onexec() can be made to accept a string
representing a profile stack.
>
> Now to the matter of whether stacking rule in the profile is required.
>
> 1. requires a rules otherwise it can be exploited, as Seth has
> already pointed out.
>
> 3. doesn't require a rule but it probably should use them, mostly
> so for consistency with 1.
>
> The question still remains whether we use change_profile rules or
> introduce a separate stacking rule.
>
> If we go with change_profile rules then
> change_profile -> A,
> change_profile -> B,
>
> grants enough permissions for stacking to A//&B, however it grants wider
> permissions than necessary as it also allows a transition to just B,
> which may not be desired. Which means at the least we need to augment
> change_profile to support the more restrictive case.
> change_profile -> A//&B,
>
> we could do the same with a special stack rule
> stack -> A//&B,
> stack -> @{SELF}//&B,
>
> but I see no reason to limit the change_profile api to not allow
> specifying compound targets. ie. I can see using change_profile to
> change_profile C//&D,
Agreed.
The existing change_profile rule could be used for specifying specific
compound targets while a new stack_profile rule could be introduced for
stacking a single or compound target with the current confinement.
> this is an immediate change to this confinement and there is no exec
> target involved. Further once delegation lands we will want to be able
> to specify targets with delegation.
> change_profile A//+E,
>
> at which point I think change_profile, stacking and delegation rules are
> more complex than combining into a single rule as each of them are going
> to have to support bits of the other.
>
> yes this does mean the stacking api is really just a convenience layer
> on top of change_profile, but that isn't a bad thing.
There's certainly a lot of overlap but if we are consistent in policy,
API, and documentation about the differences between "change" and
"stack" then I think everyone will benefit. At the minimum, everyone
will suffer a little less... :)
Tyler
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20160113/dd9b764c/attachment.pgp>
More information about the AppArmor
mailing list