[PATCH 16/18] LSM: Allow arbitrary LSM ordering

Kees Cook keescook at chromium.org
Tue Sep 18 00:00:25 UTC 2018


On Mon, Sep 17, 2018 at 3:36 PM, John Johansen
<john.johansen at canonical.com> wrote:
> On 09/17/2018 02:57 PM, Casey Schaufler wrote:
>> Modules not listed may go anywhere there is a "*" in the order.
>> An lsm.order= without a "*" is an error, and ignored.
>> If a module is specified in lsm.order but not built in it is ignored.
>> If a module is specified but disabled it is ignored.
>> The capability module goes first regardless.
>
> I don't mind using lsm.order if we must but really do not like the '*'
> idea. It makes this way more complicated than it needs to be

Having the "*" means that _not_ having it in "lsm.order=" is an
implicit form of LSM disabling. And I think we've gotten to the point
where we agree on the enable/disable logic, so I don't want to mess
that up again.

For enable/disable, I think we're agreed on:

    lsm.enable=$lsm
    lsm.disable=$lsm

lsm.disable takes precedent for disabling. (e.g. "lsm.disable=apparmor
apparmor.enable=1" will leave apparmor disabled)
lsm.enable will allow per-LSM enable/disable to operate. (e.g.
"lsm.enable=apparmor apparmor.enable=0" will leave apparmor disabled)

lsm.enable/disable ordering will be "last match": "lsm.disable=smack
lsm.enable=smack" will leave smack enabled. The legacy per-LSM
enable/disable ordering is the same, but ordering between
lsm.enable/disable and the per-LSM options is NOT ordered. i.e. the
precedent mentioned in the prior paragraph.

To support "security=", we'll still have some kind of legacy
LSM_FLAG_MAJOR to perform implicit disabling of the non-operational
other "major" LSMs. This means "security=$foo" will be a short-hand
for "lsm.disable=all-LSM_FLAG_MAJOR-who-are-not-$foo". This will
exactly match current behavior (i.e. "security=smack" and if smack
fails initialization, we do not then fall back to another major).


I think we have to support runtime ordering for the reasons John
specifies. Additionally, I have the sense that anything we can
configure in Kconfig ultimately ends up being expressed at runtime
too, so better to just make sure the design includes it now.

What we have now:

"first" then "order-doesn't-matter-minors" then "exclusive-major"

- we can't change first.
- exclusivity-ordering only matters in the face of enable/disable
which we have solved now (?)

so, ordering can be totally arbitrary after "first" (but before some
future "last"). We must not allow a token for "everything else" since
that overlaps with enable/disable, so "everything else" stay implicit
(I would argue a trailing implicit ordering).

The one complication I see with ordering, then, is that if we change
the exclusivity over time, we change what may be present on the
system. For example, right now tomoyo is exclusive. Once we have
blob-sharing, it doesn't need to be.

so: lsm.order=tomoyo  after this series means
"capability,tomoyo,yama,loadpin,integrity", but when tomoyo becomes
non-exclusive, suddenly we get
"capability,tomoyo,yama,loadpin,{selinux,smack,apparmor},integrity".
(i.e. if selinux is disabled then move on to trying smack, then
apparmor, etc.)

I would argue that this is a design feature (LSMs aren't left behind),
and order of enabled exclusive LSMs "wins" the choice for the
exclusivity (instead of operating "by name" the way "security="
works).

-Kees

-- 
Kees Cook
Pixel Security



More information about the Linux-security-module-archive mailing list