2015-12-02 22:47:55 +07:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 Juniper Networks, Inc.
|
|
|
|
*
|
|
|
|
* Author:
|
|
|
|
* Petko Manolov <petko.manolov@konsulko.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation, version 2 of the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/export.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/cred.h>
|
|
|
|
#include <linux/err.h>
|
2015-12-10 05:37:16 +07:00
|
|
|
#include <linux/init.h>
|
2016-09-01 06:05:43 +07:00
|
|
|
#include <linux/slab.h>
|
KEYS: Move the point of trust determination to __key_link()
Move the point at which a key is determined to be trustworthy to
__key_link() so that we use the contents of the keyring being linked in to
to determine whether the key being linked in is trusted or not.
What is 'trusted' then becomes a matter of what's in the keyring.
Currently, the test is done when the key is parsed, but given that at that
point we can only sensibly refer to the contents of the system trusted
keyring, we can only use that as the basis for working out the
trustworthiness of a new key.
With this change, a trusted keyring is a set of keys that once the
trusted-only flag is set cannot be added to except by verification through
one of the contained keys.
Further, adding a key into a trusted keyring, whilst it might grant
trustworthiness in the context of that keyring, does not automatically
grant trustworthiness in the context of a second keyring to which it could
be secondarily linked.
To accomplish this, the authentication data associated with the key source
must now be retained. For an X.509 cert, this means the contents of the
AuthorityKeyIdentifier and the signature data.
If system keyrings are disabled then restrict_link_by_builtin_trusted()
resolves to restrict_link_reject(). The integrity digital signature code
still works correctly with this as it was previously using
KEY_FLAG_TRUSTED_ONLY, which doesn't permit anything to be added if there
is no system keyring against which trust can be determined.
Signed-off-by: David Howells <dhowells@redhat.com>
2016-04-06 22:14:26 +07:00
|
|
|
#include <keys/system_keyring.h>
|
2015-12-02 22:47:55 +07:00
|
|
|
|
|
|
|
|
|
|
|
struct key *ima_blacklist_keyring;
|
|
|
|
|
|
|
|
/*
|
2016-04-07 15:45:23 +07:00
|
|
|
* Allocate the IMA blacklist keyring
|
2015-12-02 22:47:55 +07:00
|
|
|
*/
|
|
|
|
__init int ima_mok_init(void)
|
|
|
|
{
|
2016-09-01 06:05:43 +07:00
|
|
|
struct key_restriction *restriction;
|
|
|
|
|
2016-04-07 15:45:23 +07:00
|
|
|
pr_notice("Allocating IMA blacklist keyring.\n");
|
2015-12-02 22:47:55 +07:00
|
|
|
|
2016-09-01 06:05:43 +07:00
|
|
|
restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
|
|
|
|
if (!restriction)
|
|
|
|
panic("Can't allocate IMA blacklist restriction.");
|
|
|
|
|
|
|
|
restriction->check = restrict_link_by_builtin_trusted;
|
|
|
|
|
2015-12-02 22:47:55 +07:00
|
|
|
ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
|
|
|
|
KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
|
|
|
|
(KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
|
|
KEY_USR_VIEW | KEY_USR_READ |
|
|
|
|
KEY_USR_WRITE | KEY_USR_SEARCH,
|
KEYS: Add a facility to restrict new links into a keyring
Add a facility whereby proposed new links to be added to a keyring can be
vetted, permitting them to be rejected if necessary. This can be used to
block public keys from which the signature cannot be verified or for which
the signature verification fails. It could also be used to provide
blacklisting.
This affects operations like add_key(), KEYCTL_LINK and KEYCTL_INSTANTIATE.
To this end:
(1) A function pointer is added to the key struct that, if set, points to
the vetting function. This is called as:
int (*restrict_link)(struct key *keyring,
const struct key_type *key_type,
unsigned long key_flags,
const union key_payload *key_payload),
where 'keyring' will be the keyring being added to, key_type and
key_payload will describe the key being added and key_flags[*] can be
AND'ed with KEY_FLAG_TRUSTED.
[*] This parameter will be removed in a later patch when
KEY_FLAG_TRUSTED is removed.
The function should return 0 to allow the link to take place or an
error (typically -ENOKEY, -ENOPKG or -EKEYREJECTED) to reject the
link.
The pointer should not be set directly, but rather should be set
through keyring_alloc().
Note that if called during add_key(), preparse is called before this
method, but a key isn't actually allocated until after this function
is called.
(2) KEY_ALLOC_BYPASS_RESTRICTION is added. This can be passed to
key_create_or_update() or key_instantiate_and_link() to bypass the
restriction check.
(3) KEY_FLAG_TRUSTED_ONLY is removed. The entire contents of a keyring
with this restriction emplaced can be considered 'trustworthy' by
virtue of being in the keyring when that keyring is consulted.
(4) key_alloc() and keyring_alloc() take an extra argument that will be
used to set restrict_link in the new key. This ensures that the
pointer is set before the key is published, thus preventing a window
of unrestrictedness. Normally this argument will be NULL.
(5) As a temporary affair, keyring_restrict_trusted_only() is added. It
should be passed to keyring_alloc() as the extra argument instead of
setting KEY_FLAG_TRUSTED_ONLY on a keyring. This will be replaced in
a later patch with functions that look in the appropriate places for
authoritative keys.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2016-04-06 22:14:24 +07:00
|
|
|
KEY_ALLOC_NOT_IN_QUOTA,
|
2016-09-01 06:05:43 +07:00
|
|
|
restriction, NULL);
|
2015-12-02 22:47:55 +07:00
|
|
|
|
2016-04-07 15:45:23 +07:00
|
|
|
if (IS_ERR(ima_blacklist_keyring))
|
|
|
|
panic("Can't allocate IMA blacklist keyring.");
|
2015-11-10 21:00:38 +07:00
|
|
|
|
|
|
|
set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);
|
2015-12-02 22:47:55 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2015-12-10 05:37:16 +07:00
|
|
|
device_initcall(ima_mok_init);
|