[apparmor] "default"/"system" profile

John Johansen john.johansen at canonical.com
Tue May 21 07:49:32 UTC 2013


On 05/21/2013 12:07 AM, Steve Beattie wrote:
> On Sun, May 19, 2013 at 05:07:16AM -0700, John Johansen wrote:
>> Alright, here is a new proposal on it.
> 
> I'm generally on board. A couple of comments/questions inline:
> 
>> When a profile is created the first profile it is created with is the "init" profile.
>> - this profile is replaceable, and set as the default profile
>> - For the root namespace (namespace setup on boot)
>>   - this profile is setup in the unconfined mode
>>   - the name of this profile can be set by a kernel parameter
>>       apparmor.init=<name>
>>     or maybe
>>       apparmor.init_profile=<name>
>>   - the default name for the "init" profile could be any of (vote for your favorite)
>>     - init
>>     - initial
>>     - unconfined
>>     - something else???
> 
> I'm terrible at picking meaningful yet not unwieldy names, so no
> strong opinion from me on either name. I liked Seth's argument for
> 'initial', but really, as long as it's not called "throatwarbler
> mangrove" by default, I'll probably be okay with it. :)
> 
shoot there goes my fallback

so I goes we'll just have to go with "initial"

>> - For all other namespaces
>>   - the first profile is the "init" profile, and it is set as the default profile
> 
> The first profile loaded? So profile load order matters here? Is there
> a reason not to make this explicit in policy somehow, for non-root

yes and no. If a namespace is created as part of a profile load, that
profile will be the "init" profile and the default profile until such
time as a default profile is loaded.

This really isn't any different from kernel boot where the root namespace
is seeded with the "initial" profile.

Also this make it compatible with what we have today.

> namespaces? Or are you afraid that the difference between root and
> non-root namespace attributes will be too confusing? Do you foresee

err, I don't follow? As our namespaces have been set up each is independent
of the other, and tasks can't leave or see the higher namespace.

Each namespace needs its own default profile so that tasks can be tracked
within the namespace, the "system" default profile can not be shared
with the namespace.

It is possible for the system to "share" its policy with a child
namespace buy loading it into it. And we might add controls to do a
more direct clone but they will still have to be tracked independently.

> anything besides LXC/containers that would cause an administrator to
> specify an initial policy attrribute for a non-root namespace?
> 
The way I proposed things there is no initial policy attribute, just a
default profile attribute. In the case of initial namespace setup on
boot and setup of a child namespace that attribute points to the only
profile until a policy load defines which profile should be the default.

And yes the initial profile load when setting up a namespace could
very well have multiple profiles, and could set the default profile
attribute explicitly.

> (I note that we generally have been on a path to make things explicit
> via policy rather than rely on implicit behaviors, a direction I am
> in favor of.)
> 
yep

>>     - its name is set by the profile load that caused the creation of the namespace
>>       - namespaces are created by loading a profile to a child namespace that doesn't exist
>>       - the parent namespace can preseed policy in the child namespace
>>       - this allows lxc to setup a namespace that imitates real boot
>>     - its mode is set by the profile load
> 
> You mean whether it's in unconfined mode or not? Or something
> more/else?
> 
Right whether its unconfined or not. We don't really have a choice on
first boot but when setting up a namespace we have the ability to
seed a fully policy if we want, including what mode the profiles are in.

I assume for something like lxc it will emulate boot up, but the option
to do something different is there.


>> The default profile can be any profile in the system. That is just a regular profile that has been selected as the default profile
>>   - the "init" profile is the first default profile for a namespace
>>   - there is no set name for the default profile. That is the default profile is an attribute of the namespace
>>   - the default profile is set/changed by loading a profile that is marked as default
>>     - the marking is done as a profile flag
>>         profile foo (default) { }
>>       yes this can be combined with other profile flags
>>         profile foo (default, unconfined) { }
>>     - this allows the setting of what is default to be indicated within policy
>>     - the most recently loaded profile that is marked as default
> 
> When the notion that the default profile should be considered
> an attribute of the namespace started becoming apparent to me, I
> initially considered expressing it in policy as a mode/flag on the
> profile. I decided I didn't like that (and didn't propose it) because
> none of our other profile flags operate in the same fashion, either
> requiring the flag to be unique across the policies in the namespace,
> or specific load ordering if multiple default flags are given.
> 
true

> It comes back to my desire to grow namespaces as first class objects
> in policy (I have no doubt they are first class in implementation).
> Random hand-wavy approximation of a language extension proposal:
> 
>   namespace NAMESPACE_NAME {
>     attribute default = my_nifty_default_profile,
>   }
> 
> but that's with 15 seconds of what passes for thought on my behalf,
> with marginal consideration for consistency, etc.
> 
yeah we are going to have to think about it carefully

right now namespaces are strictly hierarchical and you never reference
your namespaces name, as from a profile level policy pov you are always
in the root namespace.


> Whether you could then define profiles within the namespace grouping...
> well, I dunno.
> 
>>     - loading of a profile that is marked as default and that is NOT a replacement for the current default does not do profile replacement on the current default
>>       eg. if "init" is the current default, and a new profile named "foo" is loaded and marked as the default profile, the tasks "confined" by init will remain confined by init, but the default profile will be switched to "foo" so that subsequent transitions to the default profile will transition to foo
> 
> Yes.
> 
>>   - transitions
>>     - u/Ux become a transition to the default profile
>>     - u/Ux becomes deprecated
>>       - we could replace it with d/Dx or something else as part of the policy language
>>   - replacement
>>     - if the default profile is replaced, its replacement becomes the default
>>     - unless another profile within the replacement set specifies it is the default
>>     - it is an error for an atomic replacement set to have to profiles marked as being the default profile
> 
> I'd like for our policy language to discourage the latter two points
> from being a problem.
>
sure, if its not marked on the profile that is easier

however its still an error to have multiple stanzas declaring different
default profiles.

>>   - removal
>>     - removal of profile within the namespace causes a replacement to the namespaces default profile
>>     - if the default profile is removed, we could do any of the following
>>       - disallow the removal (unless the namespace is being removed)
> 
> I don't care for disallowing the removal.
> 
>>       - set the default profile to unconfined mode, without actually removing it
>>       - replace with a profile named "unconfined" that is replaceable, and becomes the new default profile
> 
> I... don't have a strong opinion here, except that I prefer Seth's
> proposal to use 'default' over 'unconfined'. It does raise the issue
> if we're magically creating profiles, what if a profile by that name
> (e.g. "unconfined") already exists in the namespace?
> 
yep its a problem, I don't have a clean solution for it atm

> I could also see as another option it reverting to whatever the
> initial policy is, though I'm less than enthusiastic about it.
> 
no, the initial policy it self may have been replaced/removed

>>     - if the namespace is removed
>>       - all profiles in the namespace, including the current default profile, are replaced by the parent namespaces default profile.
> 
> What is our current behavior for processes in an existing non-root
> namespace/profile pair, if the entire namespace is removed? (I guess
> if I *really* wanted to know, I'd write a testcase or two.)
> 
It has its profile replaced to the parent namespace's unconfined profile.

The other option is to kill all tasks within the namespace that is being
removed, but we can't do this directly (well not easily). So it would
likely be achieved through some special profile replacement.

>>   - the default profile will be exposed to userspace via a file under its namespace in aafs
>>     - we could allow this file to be written to allow manually switching the default profile
> 
>> Unconfined mode transition is pix based not pux based
>> - this allows tracking different task trees with separate unconfined profiles that might later be replaced.
> 
> Agreed.
> 
> Thanks, John, for driving and persevering through all this.
> 
> 
> 




More information about the AppArmor mailing list