Re: [PATCH] X.509: Partially revert patch to add validation against IMA MOK keyring

From: David Howells
Date: Mon Jan 11 2016 - 21:03:47 EST


Mark D. Baushke <mdb@xxxxxxxxxxx> wrote:

> David Howells <dhowells@xxxxxxxxxx> writes:
>
> > Mimi Zohar <zohar@xxxxxxxxxxxxxxxxxx> wrote:
> >
> > > Is this the primary use case scenario for your patches?
> > > Unfortunately, your posted patches would break the existing IMA
> > > trust model.
> >
> > Why so?
>
> The intent is that the 'vendor' of a software solution be able to
> provide a kernel with one or more .system keys as the root of trust.
> (In many cases, this root of trust may be tied to a system that does
> measured boot as well.)

Yep.

> Further, that the 'vendor' provide a mechanism where a 'machine owner'
> is able to be delegated to add new certificate authorities to a machine
> owner keyring

Why not the .system keyring?

> The 'machine owner' key may also be used to add additional third-party
> certificate authorities or signing keys to appropriate keyrings in the
> system (generally the '.ima_mok' or the .ima keyrings).

The change I objected to makes the keys in the .system keyring and the
.ima_mok keyring effectively equivalent - so why not merge .ima_mok into
.system_keyring?

> > The patches give you per-keyring control over restricting what is
> > permitted in a keyring, allows you to use any criteria you like,
> > whether it be just the contents of that keyring or CA certs in some
> > other keyring(s) and a blacklist.
>
> Could you ellaboriate on the identify of 'you' in this case? Is it the
> vendor the system which is trying to warranty the software provided to
> the machine owner? Or, is it the 'machine owner'?

Sorry, I meant you the kernel code author. When said author calls
keyring_alloc(), they can supply a gatekeeper function as one of the
parameters. This function gets to pass judgement on any link that userspace
might try to make into a keyring. Note that *adding* a new key involves
making a link in the keyring.

See the patch ensubjected:

[RFC PATCH 14/15] KEYS: Move the point of trust determination to __key_link()

Search for keyring_alloc and particularly restrict_link_by_ima_mok.

The restriction function cannot currently be cleared or modified by userspace
- though I have an idea to make it possible to *impose* a restriction through
keyctl() on any keyring that doesn't yet have a restriction imposed.

The restriction function can impose any restrictions it likes, using the key's
parsed payload, key type, the current keyring contents and any other keyring
contents as it wishes in evaluating the trustworthiness of a key.

> > In other words, it should be able to do everything one can do now -
> > except that it controls linkage between trusted keyrings with the same
> > restrictions as adding new keys.
>
> Hmmm... I suspect I may be missing something.

Currently we're using the KEY_FLAG_TRUSTED and KEY_FLAG_TRUSTED_ONLY key flags
to gatekeeper a additions to a keyring. KEY_FLAG_TRUSTED is set when a new
proposed key is parsed, using the contents of .system_keyring - and now
.ima_mok - as the authority source. KEY_FLAG_TRUSTED_ONLY is set on a keyring
just after it is created (a window of opportunity which doesn't matter for
pre-module keyrings). KEY_FLAG_TRUSTED_ONLY means that only keys marked
KEY_FLAG_TRUSTED may be *added* to a keyring. It doesn't gate against linking
trusted keys between keyrings.

> If the 'vendor' selling the software desires that the 'machine owner'
> not extend the kernel with new kernel modules, how is that provided for
> in your linkage model?

If .system_keyring was writable:

keyctl clear %:.system_keyring

would prevent any new keys from being added and would prevent signed modules
from being loaded.

> Another use case, is that the 'vendor' trusts a third-party to properly
> deliver both LKMs and user-land programs, but only if the 'machine
> owner' explicitly authorizes the keys for that 'third-party' explicitly.
>
> As you may see here, I am attempting to outline a use modle where it is
> possible to build up a hierarchy tree of trust rather than a flat set of
> keys that are all-powerful.

However, given that the KEY_FLAG_TRUSTED mark is somewhat naive in its
operation, .system_keyring and .ima_mok are effectively unioned. In the log
message of the commit I want to partially revert, the .ima_mok is not
self-allowing - which at least makes it worth differentiating, though that's
not what the code change actually does.

> Keeping signing keys separate from delegated certificate authority keys
> is also important.

Signing keys go in .ima only?

> > So if it breaks the IMA trust model, then doesn't that suggest that
> > the trust model is broken anyway?
>
> It is possible that I do not properly understand your new per-key
> control over a keyring. I would welcome enlightenment.
>
> One of the fundamental assumptions of a big server is that a kernel that
> might need to be running non-stop for many years, but might unload and
> reload LKMs more often than that and will certainly have the possibility
> of updating user-land software (hopefully without needing a reboot) on a
> periodic basis.
>
> I hope that my message provides some insight into the problem at hand.

It still doesn't clarify entirely why .ima_mok exists separately from
.system_keyring from a technical point of view.

David