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

John Johansen john.johansen at canonical.com
Thu Jan 14 08:46:24 UTC 2016


On 01/13/2016 08:08 PM, Seth Arnold wrote:
> On Tue, Jan 12, 2016 at 03:10:28PM -0800, John Johansen wrote:
>> 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
>>
>> 2. stack_onexec, stack delayed until exec applied pre-exec transitions
>>   A -- stack_onexec B -- exec apply stack -- A//&B -- exec trans --> C//&D
>>
>> 3. stack_onexec, stack delayed until exec applied post-exec transitions
>>   A -- stack_onexec B -- exec trans -- C -- apply stack --> C//&B
>>
>> each is a viable definition and each could have their uses.
> 
> This is perfect; I had been envisioning #2 before this series of emails.
> I didn't like #1 much when I read it in Tyler's proposed manpage. I think
> I prefer #3 now that I've had some time to think about this.
> 
>> 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.
> 
> I think I don't like requiring rules for this approach. Two of the uses of
> stacking that I envision are to reduce privileges without requiring
> editing of distro-supplied profiles. Editing the distro-provided profiles
> to explicitly describe the stacking may be more complicated than just
> re-writing the distro profiles in the first place and avoiding stacking.
> (Yeah, the future delegation work could provide a different solution to
> my problem.)
> 

I get the desire. My concern is that people will be confused by the
subtle difference between requiring rules and not requiring rules.

Another potential solution is if the target label is a subset of the
current label then no rule is required.

Eg.
  A -> A//&B                 # is subset
  A//&B -> A//&B//&C         # is subset
  A//&B -> A//&C             # NOT a subset

for the transition that is delayed to exec time its label would have
to be a subset of what is allowed by change_profile or exec rules.

Note: in change_profile rules
     change_profile /exec -> target,
  means this change_profile is allowed only if an /exec is matched at
  exec time. This is currently supported, and results in a double
  pass at permission check.  At the change_onexec api call
     change_profile /** -> target,
  is checked, because an exec match is not possible at this time,
  but we can check if target is in the set of what is allowed. At
  exec we then check the full rule and fail if the match is not
  done.

Eg. say we are confined by A and have a rule
  px /** -> C,

  A -- stack_onexec --> A//&B         # not allowed
  A -- change_onexec --> A            # not allowed
  A -- change_onexec --> B&//C        # allowed via px /** -> C
  A -- change_onexec --> B            # not allowed
  A -- change_onexec --> C//&B        # allowed via px /** -> C
  A -- change_onexec --> C            # allowed via px /** -> C

now say our rule set is
  px /** -> C,
  change_profile /** -> A,

  A -- stack_onexec --> A//&B         # allowed via change_profile /** -> A
  A -- change_onexec --> A            # allowed via change_profile /** -> A
  A -- change_onexec --> B&//C        # allowed via px /** -> C
  A -- change_onexec --> B            # not allowed
  A -- change_onexec --> C//&B        # allowed via px /** -> C
  A -- change_onexec --> C            # allowed via px /** -> C

now say our rule set is
  px /** -> C,
  change_profile /** -> A//&B

  A -- stack_onexec --> A//&B         # allowed via change_profile /** -> A//&B
  A -- change_onexec --> A            # not allowed
  A -- change_onexec --> B&//C        # allowed via px /** -> C
  A -- change_onexec --> B            # not allowed
  A -- change_onexec --> C//&B        # allowed via px /** -> C
  A -- change_onexec --> C            # allowed via px /** -> C

etc. I think that is enough to demonstrate the concept
change/stack_onexec - could be allowed as long as it is a subset of
what is allowed by the change_profile and exec rules.

plane stack/change_profile allowed if it is subset of current
confinement or what is allowed by change_profile rules.

>> 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,
>>
>> 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
> 
> These all feel fairly subtle. The explicit stack rules are clear enough,
> but the leading & is probably too easy to overlook. The @{SELF} variable
> might be too hard to explain vs the @{profile_name} variable.
> 
> How about:
>   px /** -> stack &B,  ix /** -> stack &B,
> or:
>   px /** -> stack B,  ix /** -> stack B,
> 

meh, the extra keyword doesn't do much for me, but I am all too familiar
with the //& syntax so I am probably a poor judge. I'd like to here what
other people think.

>> 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.
> 
> I'm less sure about this. I haven't figured out what I'd like the policy
> to look like for the different kinds of stacking that I've envisioned,
> especially since some of the reasons is because I want to use "upstream"
> policy unchanged but still tighten it due to administrative needs or
> personal preferences.
> 

sure, how about the alternate solution I proposed above. I think it still
unifies 1 and 3 in when rules are required, is looser in that you can
enter subsets without rules, and should still prevent the attack you
originally raised.





More information about the AppArmor mailing list