Questions regarding partial policy load, and the future

John Johansen john.johansen at canonical.com
Sat Jun 19 00:26:57 BST 2010


On 06/18/2010 01:00 PM, Kees Cook wrote:
> Hi John,
> 
> On Fri, Jun 18, 2010 at 12:19:27PM -0700, John Johansen wrote:
>> However there are several reasons to change this and have policy, or
>> parts of policy, sharing information and loaded together.  The caveat
>> is that with sharing the ability to load profiles separately is lost.
>> So the question becomes how important is being able to load profiles
>> individually?  How often are individual profile reloads used instead of
>> just reloading all of policy through the init scripts?
> 
> Right now, all the time.  The idea of on-demand loading for only things
> that are about to start up is how it's split up now to spread out the
> potential load times.
> 
Right, at the moment we have split load, where we load the early set
and then, reload the whole set later.

>> If AppArmor switched to a total policy load model the ability to load
>> individual profiles could be simulated by allowing the specification
>> of the profile to load and then grabbing the rest of policy and
>> recompiling and loading.  To cut down on recompile time policy could
>> be cached and precompiled pieces could be linked together.
> 
> It would be a matter of time more than anything else.  If "change one
> profile" means "reload all profiles" and it's still atomic, etc, I guess
It would be atomic

> that's okay, but I worry it'll be a big problem for people with lots of
> hats.
> 
I am not so sure about that.  How many people are using external hats?
Currently the parser processes internal hats with the rest of the profile
so changing 1 hat means recompiling the whole profile, its only at the
last stage where the profile and hats are loaded individually.

In this case it is actually faster to load the profile and hats in
one go instead of individually as there are fewer context switches
and less locking.  It is something I have prototyped and played with
but not finished yet.

>> * Networking will require it, well at least for part of the network
>>   policy.  Currently network mediation is very rudimentary.  This is
>>   partly because to support packet based mediation at least part of
>>   the networking rule set is going to have to be computed across all
>>   profiles and loaded as a single global set.
> 
> What about "if network rules change, all profiles must be reloaded"?
> 
Well there are two ways to do it.  For both the packet based portion
of network rules must be computed globally.  The portion could
be reloaded independent of profiles and the profiles could refer
to it, so its a global chunk external to the profiles.  Which
are still independent.  The other way to handle it is to just make
it part of policy where it and the profiles are all loaded together
allowing for maximum sharing.

There is also a third possibility akin the first where network rules
are globally computed and some profiles do sharing.  Eg. Hats, and
all profiles within a given file could be compiled together and
share their parts.  This gives some of the size reduction benefits
but won't provide the "labeling" speedups that can be had be
a total policy compile.

>> * Total policy load will reduce the size of policy as currently
>>   there is a lot of redundancy and being able to share dfas
>>   will result in smaller compiled policy sizes.  As an example
>>   the current Ubuntu evince profile, is actually 3 profiles that
>>   share a lot in common, and if their dfas were combined total
>>   policy size would shrink by about half.
> 
> Yeah, this would be pretty nice.
> 
Some of this could be picked up by the partial sharing I mention
above.

>>   This will also be beneficial for kernel side variables, of which
>>   at least some will have to be loaded from a global view instead
>>   of a per profile view
> 
> Yup.
> 
>> * Total policy load will allow computing shared "labeling" values
>>   that will allow speeding up some parts of the kernel mediation
>>   (less revalidation, etc).  And also is beneficial to a hybrid
>>   model, where on disk label can be selectively used.
> 
> Also good.
> 
>> None of these reason require moving to a total policy load for
>> everything.  The load could be split and only the parts of networking
>> and kernel side variables that require it could be loaded in the
>> total policy manner.
>>
I somewhat lied, the shared "labeling" does require global policy
compile but that is only used for optimizations and isn't required
for enforcement.  It would be nice for working in with a hybrid model
but is not required

>> However if the computations need to be done for those then its a
>> small step to do it for everything and in so doing pickup all
>> the benefits of a total policy load.
> 
> Another idea to handle the time-to-fully-load issue here would be to have
> a complete "early boot" profile, and then early boot is done, switch to
> "everything", which replaces the early boot.  Which, is basically the
> simulated partial loading.
> 
> It sounds like it's got to happen, but I think it's going to be pretty
> painful as far as boot times.

Not necessarily.  The early boot profile really could just be a list
of profiles to compile into a single early policy file that is cached
separate from the system file.  A second cached compiled policy file
would be created for the later replacement load of total policy.

This could in fact speed up loads as the compiled policy should be
smaller, policy compilation also could be faster as more redundancies
could be detected and eliminated in early phases of the compile,
so that the dfa generation phase of the compile generates less states
in total meaning, less states to minimize and less states to compress.



More information about the AppArmor mailing list