From: Mimi Zohar <zohar@linux.vnet.ibm.com>
To: David Howells <dhowells@redhat.com>
Cc: linux-security-module@vger.kernel.org, keyrings@vger.kernel.org,
petkan@mip-labs.com, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 07/20] KEYS: Add a facility to restrict new links into a keyring [ver #2]
Date: Mon, 08 Feb 2016 06:59:17 -0500 [thread overview]
Message-ID: <1454932757.2648.143.camel@linux.vnet.ibm.com> (raw)
In-Reply-To: <20160119113118.23238.44239.stgit@warthog.procyon.org.uk>
On Tue, 2016-01-19 at 11:31 +0000, David Howells wrote:
> 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>
Rephrase restrict_link documentation comment inline below.
Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
> ---
>
> Documentation/security/keys.txt | 14 ++++++++++
> certs/blacklist.c | 2 +
> certs/system_keyring.c | 8 +++---
> fs/cifs/cifsacl.c | 2 +
> fs/nfs/nfs4idmap.c | 2 +
> include/linux/key.h | 48 ++++++++++++++++++++++++++++-------
> net/dns_resolver/dns_key.c | 2 +
> net/rxrpc/ar-key.c | 4 +--
> security/integrity/digsig.c | 7 ++---
> security/integrity/ima/ima_mok.c | 8 +++---
> security/keys/key.c | 43 ++++++++++++++++++++++++++-----
> security/keys/keyring.c | 52 +++++++++++++++++++++++++++++++++-----
> security/keys/persistent.c | 4 +--
> security/keys/process_keys.c | 16 +++++++-----
> security/keys/request_key.c | 4 +--
> security/keys/request_key_auth.c | 2 +
> 16 files changed, 165 insertions(+), 53 deletions(-)
>
> diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
> index 8c183873b2b7..3e2e958f2091 100644
> --- a/Documentation/security/keys.txt
> +++ b/Documentation/security/keys.txt
> @@ -999,6 +999,10 @@ payload contents" for more information.
> struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
> const struct cred *cred,
> key_perm_t perm,
> + int (*restrict_link)(struct key *,
> + const struct key_type *,
> + unsigned long,
> + const union key_payload *),
> unsigned long flags,
> struct key *dest);
>
> @@ -1010,6 +1014,16 @@ payload contents" for more information.
> KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
> towards the user's quota). Error ENOMEM can also be returned.
>
> + If restrict_link not NULL, it should point to a function will be called to
> + vet all attempts to link keys into the keyring, though this can be
> + overridden by passing KEY_ALLOC_BYPASS_RESTRICTION to
> + key_create_or_update().
Please fix the first part of the sentence. Maybe add an example of
when it is appropriate to bypass the restriction - (eg. loading the
builtin keys).
> +
> + When called, the restriction function will be passed the keyring being
> + added to, the key flags value and the type and payload of the key being
> + added. Note that when a new key is being created, this is called between
> + payload preparsing and actual key creation.
> +
>
> (*) To check the validity of a key, this function can be called:
>
> diff --git a/certs/blacklist.c b/certs/blacklist.c
> index 5f54baae3a32..7f769479c17b 100644
> --- a/certs/blacklist.c
> +++ b/certs/blacklist.c
> @@ -148,7 +148,7 @@ static int __init blacklist_init(void)
> KEY_USR_SEARCH,
> KEY_ALLOC_NOT_IN_QUOTA |
> KEY_FLAG_KEEP,
> - NULL);
> + NULL, NULL);
> if (IS_ERR(blacklist_keyring))
> panic("Can't allocate system blacklist keyring\n");
>
> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> index dc18869ff680..417d65882870 100644
> --- a/certs/system_keyring.c
> +++ b/certs/system_keyring.c
> @@ -36,11 +36,10 @@ static __init int system_trusted_keyring_init(void)
> KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
> ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA,
> + keyring_restrict_trusted_only, NULL);
> if (IS_ERR(system_trusted_keyring))
> panic("Can't allocate system trusted keyring\n");
> -
> - set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
> return 0;
> }
>
> @@ -85,7 +84,8 @@ static __init int load_system_certificate_list(void)
> KEY_USR_VIEW | KEY_USR_READ),
> KEY_ALLOC_NOT_IN_QUOTA |
> KEY_ALLOC_TRUSTED |
> - KEY_ALLOC_BUILT_IN);
> + KEY_ALLOC_BUILT_IN |
> + KEY_ALLOC_BYPASS_RESTRICTION);
> if (IS_ERR(key)) {
> pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
> PTR_ERR(key));
> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
> index 3f93125916bf..71e8a56e9479 100644
> --- a/fs/cifs/cifsacl.c
> +++ b/fs/cifs/cifsacl.c
> @@ -360,7 +360,7 @@ init_cifs_idmap(void)
> GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
> (KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ,
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
> if (IS_ERR(keyring)) {
> ret = PTR_ERR(keyring);
> goto failed_put_cred;
> diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
> index 5ba22c6b0ffa..c444285bb1b1 100644
> --- a/fs/nfs/nfs4idmap.c
> +++ b/fs/nfs/nfs4idmap.c
> @@ -201,7 +201,7 @@ int nfs_idmap_init(void)
> GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
> (KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ,
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
> if (IS_ERR(keyring)) {
> ret = PTR_ERR(keyring);
> goto failed_put_cred;
> diff --git a/include/linux/key.h b/include/linux/key.h
> index 5f5b1129dc92..c331b8bed035 100644
> --- a/include/linux/key.h
> +++ b/include/linux/key.h
> @@ -174,10 +174,9 @@ struct key {
> #define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
> #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
> #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */
> -#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */
> -#define KEY_FLAG_BUILTIN 10 /* set if key is builtin */
> -#define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */
> -#define KEY_FLAG_KEEP 12 /* set if key should not be removed */
> +#define KEY_FLAG_BUILTIN 9 /* set if key is built in to the kernel */
> +#define KEY_FLAG_ROOT_CAN_INVAL 10 /* set if key can be invalidated by root without permission */
> +#define KEY_FLAG_KEEP 11 /* set if key should not be removed */
>
> /* the key type and key description string
> * - the desc is used to match a key against search criteria
> @@ -205,6 +204,21 @@ struct key {
> };
> int reject_error;
> };
> +
> + /* This is set on a keyring to restrict the addition of a link to a key
> + * to it. If this method isn't provided then it is assumed that the
> + * keyring is open to any addition. It is ignored for non-keyring
> + * keys.
> + *
> + * This is intended for use with rings of trusted keys whereby addition
> + * to the keyring needs to be controlled. KEY_ALLOC_BYPASS_RESTRICTION
> + * overrides this, allowing the kernel to add extra keys without
> + * restriction.
> + */
> + int (*restrict_link)(struct key *keyring,
> + const struct key_type *type,
> + unsigned long flags,
> + const union key_payload *payload);
> };
>
> extern struct key *key_alloc(struct key_type *type,
> @@ -212,14 +226,19 @@ extern struct key *key_alloc(struct key_type *type,
> kuid_t uid, kgid_t gid,
> const struct cred *cred,
> key_perm_t perm,
> - unsigned long flags);
> + unsigned long flags,
> + int (*restrict_link)(struct key *,
> + const struct key_type *,
> + unsigned long,
> + const union key_payload *));
>
>
> -#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */
> -#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
> -#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
> -#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */
> -#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */
> +#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */
> +#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
> +#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
> +#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */
> +#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */
> +#define KEY_ALLOC_BYPASS_RESTRICTION 0x0010 /* Override the check on restricted keyrings */
>
> extern void key_revoke(struct key *key);
> extern void key_invalidate(struct key *key);
> @@ -288,8 +307,17 @@ extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid
> const struct cred *cred,
> key_perm_t perm,
> unsigned long flags,
> + int (*restrict_link)(struct key *,
> + const struct key_type *,
> + unsigned long,
> + const union key_payload *),
> struct key *dest);
>
> +extern int keyring_restrict_trusted_only(struct key *keyring,
> + const struct key_type *type,
> + unsigned long,
> + const union key_payload *payload);
> +
> extern int keyring_clear(struct key *keyring);
>
> extern key_ref_t keyring_search(key_ref_t keyring,
> diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
> index c79b85eb4d4c..8737412c7b27 100644
> --- a/net/dns_resolver/dns_key.c
> +++ b/net/dns_resolver/dns_key.c
> @@ -281,7 +281,7 @@ static int __init init_dns_resolver(void)
> GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
> (KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ,
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
> if (IS_ERR(keyring)) {
> ret = PTR_ERR(keyring);
> goto failed_put_cred;
> diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
> index 3f6571651d32..b8e87a16c544 100644
> --- a/net/rxrpc/ar-key.c
> +++ b/net/rxrpc/ar-key.c
> @@ -965,7 +965,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
>
> key = key_alloc(&key_type_rxrpc, "x",
> GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
> - KEY_ALLOC_NOT_IN_QUOTA);
> + KEY_ALLOC_NOT_IN_QUOTA, NULL);
> if (IS_ERR(key)) {
> _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
> return -ENOMEM;
> @@ -1012,7 +1012,7 @@ struct key *rxrpc_get_null_key(const char *keyname)
>
> key = key_alloc(&key_type_rxrpc, keyname,
> GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
> - KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
> + KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
> if (IS_ERR(key))
> return key;
>
> diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
> index 8ef15118cc78..659566c2200b 100644
> --- a/security/integrity/digsig.c
> +++ b/security/integrity/digsig.c
> @@ -83,10 +83,9 @@ int __init integrity_init_keyring(const unsigned int id)
> ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ |
> KEY_USR_WRITE | KEY_USR_SEARCH),
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> - if (!IS_ERR(keyring[id]))
> - set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags);
> - else {
> + KEY_ALLOC_NOT_IN_QUOTA,
> + NULL, NULL);
> + if (IS_ERR(keyring[id])) {
> err = PTR_ERR(keyring[id]);
> pr_info("Can't allocate %s keyring (%d)\n",
> keyring_name[id], err);
> diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
> index 676885e4320e..ef91248cb934 100644
> --- a/security/integrity/ima/ima_mok.c
> +++ b/security/integrity/ima/ima_mok.c
> @@ -35,20 +35,20 @@ __init int ima_mok_init(void)
> (KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ |
> KEY_USR_WRITE | KEY_USR_SEARCH,
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA,
> + keyring_restrict_trusted_only, NULL);
>
> 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,
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA,
> + keyring_restrict_trusted_only, NULL);
>
> if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring))
> panic("Can't allocate IMA MOK or blacklist keyrings.");
> - set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);
>
> - set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);
> set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);
> return 0;
> }
> diff --git a/security/keys/key.c b/security/keys/key.c
> index 48dbfa543bcb..23b271b1834d 100644
> --- a/security/keys/key.c
> +++ b/security/keys/key.c
> @@ -201,6 +201,7 @@ serial_exists:
> * @cred: The credentials specifying UID namespace.
> * @perm: The permissions mask of the new key.
> * @flags: Flags specifying quota properties.
> + * @restrict_link: Optional link restriction method for new keyrings.
> *
> * Allocate a key of the specified type with the attributes given. The key is
> * returned in an uninstantiated state and the caller needs to instantiate the
> @@ -223,7 +224,11 @@ serial_exists:
> */
> struct key *key_alloc(struct key_type *type, const char *desc,
> kuid_t uid, kgid_t gid, const struct cred *cred,
> - key_perm_t perm, unsigned long flags)
> + key_perm_t perm, unsigned long flags,
> + int (*restrict_link)(struct key *,
> + const struct key_type *,
> + unsigned long,
> + const union key_payload *))
> {
> struct key_user *user = NULL;
> struct key *key;
> @@ -291,6 +296,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
> key->uid = uid;
> key->gid = gid;
> key->perm = perm;
> + key->restrict_link = restrict_link;
>
> if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
> key->flags |= 1 << KEY_FLAG_IN_QUOTA;
> @@ -495,6 +501,12 @@ int key_instantiate_and_link(struct key *key,
> }
>
> if (keyring) {
> + if (keyring->restrict_link) {
> + ret = keyring->restrict_link(keyring, key->type,
> + key->flags, &prep.payload);
> + if (ret < 0)
> + goto error;
> + }
> ret = __key_link_begin(keyring, &key->index_key, &edit);
> if (ret < 0)
> goto error;
> @@ -550,8 +562,12 @@ int key_reject_and_link(struct key *key,
> awaken = 0;
> ret = -EBUSY;
>
> - if (keyring)
> + if (keyring) {
> + if (keyring->restrict_link)
> + return -EPERM;
> +
> link_ret = __key_link_begin(keyring, &key->index_key, &edit);
> + }
>
> mutex_lock(&key_construction_mutex);
>
> @@ -792,6 +808,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
> struct key *keyring, *key = NULL;
> key_ref_t key_ref;
> int ret;
> + int (*restrict_link)(struct key *,
> + const struct key_type *,
> + unsigned long,
> + const union key_payload *) = NULL;
>
> /* look up the key type to see if it's one of the registered kernel
> * types */
> @@ -810,6 +830,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
>
> key_check(keyring);
>
> + key_ref = ERR_PTR(-EPERM);
> + if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
> + restrict_link = keyring->restrict_link;
> +
> key_ref = ERR_PTR(-ENOTDIR);
> if (keyring->type != &key_type_keyring)
> goto error_put_type;
> @@ -834,10 +858,15 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
> }
> index_key.desc_len = strlen(index_key.description);
>
> - key_ref = ERR_PTR(-EPERM);
> - if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags))
> - goto error_free_prep;
> - flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0;
> + if (restrict_link) {
> + unsigned long kflags = prep.trusted ? KEY_FLAG_TRUSTED : 0;
> + ret = restrict_link(keyring,
> + index_key.type, kflags, &prep.payload);
> + if (ret < 0) {
> + key_ref = ERR_PTR(ret);
> + goto error_free_prep;
> + }
> + }
>
> ret = __key_link_begin(keyring, &index_key, &edit);
> if (ret < 0) {
> @@ -878,7 +907,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
>
> /* allocate a new key */
> key = key_alloc(index_key.type, index_key.description,
> - cred->fsuid, cred->fsgid, cred, perm, flags);
> + cred->fsuid, cred->fsgid, cred, perm, flags, NULL);
> if (IS_ERR(key)) {
> key_ref = ERR_CAST(key);
> goto error_link_end;
> diff --git a/security/keys/keyring.c b/security/keys/keyring.c
> index f931ccfeefb0..ea023ca6d217 100644
> --- a/security/keys/keyring.c
> +++ b/security/keys/keyring.c
> @@ -491,13 +491,18 @@ static long keyring_read(const struct key *keyring,
> */
> struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
> const struct cred *cred, key_perm_t perm,
> - unsigned long flags, struct key *dest)
> + unsigned long flags,
> + int (*restrict_link)(struct key *,
> + const struct key_type *,
> + unsigned long,
> + const union key_payload *),
> + struct key *dest)
> {
> struct key *keyring;
> int ret;
>
> keyring = key_alloc(&key_type_keyring, description,
> - uid, gid, cred, perm, flags);
> + uid, gid, cred, perm, flags, restrict_link);
> if (!IS_ERR(keyring)) {
> ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
> if (ret < 0) {
> @@ -510,6 +515,30 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
> }
> EXPORT_SYMBOL(keyring_alloc);
>
> +/**
> + * keyring_restrict_trusted_only - Restrict additions to a keyring to trusted keys only
> + * @keyring: The keyring being added to.
> + * @type: The type of key being added.
> + * @flags: The key flags.
> + * @payload: The payload of the key intended to be added.
> + *
> + * Reject the addition of any links to a keyring that point to keys that aren't
> + * marked as being trusted. It can be overridden by passing
> + * KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when adding a key
> + * to a keyring.
> + *
> + * This is meant to be passed as the restrict_link parameter to
> + * keyring_alloc().
> + */
> +int keyring_restrict_trusted_only(struct key *keyring,
> + const struct key_type *type,
> + unsigned long flags,
> + const union key_payload *payload)
> +{
> +
> + return flags & KEY_FLAG_TRUSTED ? 0 : -EPERM;
> +}
> +
> /*
> * By default, we keys found by getting an exact match on their descriptions.
> */
> @@ -1191,6 +1220,17 @@ void __key_link_end(struct key *keyring,
> up_write(&keyring->sem);
> }
>
> +/*
> + * Check addition of keys to restricted keyrings.
> + */
> +static int __key_link_check_restriction(struct key *keyring, struct key *key)
> +{
> + if (!keyring->restrict_link)
> + return 0;
> + return keyring->restrict_link(keyring,
> + key->type, key->flags, &key->payload);
> +}
> +
> /**
> * key_link - Link a key to a keyring
> * @keyring: The keyring to make the link in.
> @@ -1221,14 +1261,12 @@ int key_link(struct key *keyring, struct key *key)
> key_check(keyring);
> key_check(key);
>
> - if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&
> - !test_bit(KEY_FLAG_TRUSTED, &key->flags))
> - return -EPERM;
> -
> ret = __key_link_begin(keyring, &key->index_key, &edit);
> if (ret == 0) {
> kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));
> - ret = __key_link_check_live_key(keyring, key);
> + ret = __key_link_check_restriction(keyring, key);
> + if (ret == 0)
> + ret = __key_link_check_live_key(keyring, key);
> if (ret == 0)
> __key_link(key, &edit);
> __key_link_end(keyring, &key->index_key, edit);
> diff --git a/security/keys/persistent.c b/security/keys/persistent.c
> index c9fae5ea89fe..2ef45b319dd9 100644
> --- a/security/keys/persistent.c
> +++ b/security/keys/persistent.c
> @@ -26,7 +26,7 @@ static int key_create_persistent_register(struct user_namespace *ns)
> current_cred(),
> ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ),
> - KEY_ALLOC_NOT_IN_QUOTA, NULL);
> + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
> if (IS_ERR(reg))
> return PTR_ERR(reg);
>
> @@ -60,7 +60,7 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
> uid, INVALID_GID, current_cred(),
> ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
> KEY_USR_VIEW | KEY_USR_READ),
> - KEY_ALLOC_NOT_IN_QUOTA,
> + KEY_ALLOC_NOT_IN_QUOTA, NULL,
> ns->persistent_keyring_register);
> if (IS_ERR(persistent))
> return ERR_CAST(persistent);
> diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
> index a3f85d2a00bb..9bb6bb5fd845 100644
> --- a/security/keys/process_keys.c
> +++ b/security/keys/process_keys.c
> @@ -76,7 +76,8 @@ int install_user_keyrings(void)
> if (IS_ERR(uid_keyring)) {
> uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
> cred, user_keyring_perm,
> - KEY_ALLOC_IN_QUOTA, NULL);
> + KEY_ALLOC_IN_QUOTA,
> + NULL, NULL);
> if (IS_ERR(uid_keyring)) {
> ret = PTR_ERR(uid_keyring);
> goto error;
> @@ -92,7 +93,8 @@ int install_user_keyrings(void)
> session_keyring =
> keyring_alloc(buf, user->uid, INVALID_GID,
> cred, user_keyring_perm,
> - KEY_ALLOC_IN_QUOTA, NULL);
> + KEY_ALLOC_IN_QUOTA,
> + NULL, NULL);
> if (IS_ERR(session_keyring)) {
> ret = PTR_ERR(session_keyring);
> goto error_release;
> @@ -134,7 +136,8 @@ int install_thread_keyring_to_cred(struct cred *new)
>
> keyring = keyring_alloc("_tid", new->uid, new->gid, new,
> KEY_POS_ALL | KEY_USR_VIEW,
> - KEY_ALLOC_QUOTA_OVERRUN, NULL);
> + KEY_ALLOC_QUOTA_OVERRUN,
> + NULL, NULL);
> if (IS_ERR(keyring))
> return PTR_ERR(keyring);
>
> @@ -180,7 +183,8 @@ int install_process_keyring_to_cred(struct cred *new)
>
> keyring = keyring_alloc("_pid", new->uid, new->gid, new,
> KEY_POS_ALL | KEY_USR_VIEW,
> - KEY_ALLOC_QUOTA_OVERRUN, NULL);
> + KEY_ALLOC_QUOTA_OVERRUN,
> + NULL, NULL);
> if (IS_ERR(keyring))
> return PTR_ERR(keyring);
>
> @@ -231,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
>
> keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
> KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
> - flags, NULL);
> + flags, NULL, NULL);
> if (IS_ERR(keyring))
> return PTR_ERR(keyring);
> } else {
> @@ -785,7 +789,7 @@ long join_session_keyring(const char *name)
> keyring = keyring_alloc(
> name, old->uid, old->gid, old,
> KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
> - KEY_ALLOC_IN_QUOTA, NULL);
> + KEY_ALLOC_IN_QUOTA, NULL, NULL);
> if (IS_ERR(keyring)) {
> ret = PTR_ERR(keyring);
> goto error2;
> diff --git a/security/keys/request_key.c b/security/keys/request_key.c
> index c7a117c9a8f3..a29e3554751e 100644
> --- a/security/keys/request_key.c
> +++ b/security/keys/request_key.c
> @@ -116,7 +116,7 @@ static int call_sbin_request_key(struct key_construction *cons,
> cred = get_current_cred();
> keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
> KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
> - KEY_ALLOC_QUOTA_OVERRUN, NULL);
> + KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
> put_cred(cred);
> if (IS_ERR(keyring)) {
> ret = PTR_ERR(keyring);
> @@ -355,7 +355,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
>
> key = key_alloc(ctx->index_key.type, ctx->index_key.description,
> ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
> - perm, flags);
> + perm, flags, NULL);
> if (IS_ERR(key))
> goto alloc_failed;
>
> diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
> index 4f0f112fe276..9db8b4a82787 100644
> --- a/security/keys/request_key_auth.c
> +++ b/security/keys/request_key_auth.c
> @@ -202,7 +202,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
> authkey = key_alloc(&key_type_request_key_auth, desc,
> cred->fsuid, cred->fsgid, cred,
> KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
> - KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
> + KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
> if (IS_ERR(authkey)) {
> ret = PTR_ERR(authkey);
> goto error_alloc;
>
next prev parent reply other threads:[~2016-02-08 12:00 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-19 11:30 [RFC PATCH 00/20] KEYS: Restrict additions to 'trusted' keyrings [ver #2] David Howells
2016-01-19 11:30 ` [RFC PATCH 01/20] KEYS: Add an alloc flag to convey the builtinness of a key " David Howells
2016-01-20 18:58 ` Mimi Zohar
2016-02-03 15:30 ` David Howells
2016-01-19 11:30 ` [RFC PATCH 02/20] KEYS: Add a system blacklist keyring " David Howells
2016-01-20 19:31 ` Mimi Zohar
2016-02-03 15:27 ` David Howells
2016-02-08 13:34 ` Mimi Zohar
2016-02-08 13:55 ` David Howells
2016-02-08 15:03 ` Mimi Zohar
2016-02-08 15:53 ` How to add additional blacklist entries? David Howells
2016-02-08 16:32 ` Mimi Zohar
2016-02-08 16:43 ` David Howells
2016-02-08 19:28 ` Mimi Zohar
2016-02-09 10:42 ` David Howells
2016-02-10 14:07 ` Mimi Zohar
2016-02-08 14:55 ` [RFC PATCH 02/20] KEYS: Add a system blacklist keyring [ver #2] David Howells
2016-02-08 16:39 ` Mimi Zohar
2016-02-19 11:48 ` David Howells
2016-01-20 20:26 ` Mimi Zohar
2016-02-03 15:29 ` David Howells
2016-01-19 11:30 ` [RFC PATCH 03/20] X.509: Allow X.509 certs to be blacklisted " David Howells
2016-01-20 20:33 ` Mimi Zohar
2016-02-03 15:46 ` David Howells
2016-02-05 16:16 ` Mimi Zohar
2016-01-19 11:30 ` [RFC PATCH 04/20] X.509: Don't treat self-signed keys specially " David Howells
2016-01-20 20:40 ` Mimi Zohar
2016-01-19 11:31 ` [RFC PATCH 05/20] KEYS: Generalise system_verify_data() to provide access to internal content " David Howells
2016-01-19 11:31 ` [RFC PATCH 06/20] PKCS#7: Make trust determination dependent on contents of trust keyring " David Howells
2016-01-19 11:31 ` [RFC PATCH 07/20] KEYS: Add a facility to restrict new links into a " David Howells
2016-02-08 11:59 ` Mimi Zohar [this message]
2016-02-29 15:49 ` David Howells
2016-01-19 11:31 ` [RFC PATCH 08/20] KEYS: Allow authentication data to be stored in an asymmetric key " David Howells
2016-01-19 11:31 ` [RFC PATCH 09/20] KEYS: Add identifier pointers to public_key_signature struct " David Howells
2016-01-19 11:31 ` [RFC PATCH 10/20] X.509: Retain the key verification data " David Howells
2016-01-19 11:31 ` [RFC PATCH 11/20] X.509: Extract signature digest and make self-signed cert checks earlier " David Howells
2016-01-19 11:31 ` [RFC PATCH 12/20] PKCS#7: Make the signature a pointer rather than embedding it " David Howells
2016-02-08 12:00 ` Mimi Zohar
2016-02-19 11:56 ` David Howells
2016-01-19 11:32 ` [RFC PATCH 13/20] X.509: Move the trust validation code out to its own file " David Howells
2016-02-08 11:59 ` Mimi Zohar
2016-01-19 11:32 ` [RFC PATCH 14/20] KEYS: Generalise x509_request_asymmetric_key() " David Howells
2016-02-08 11:59 ` Mimi Zohar
2016-01-19 11:32 ` [RFC PATCH 15/20] KEYS: Move the point of trust determination to __key_link() " David Howells
2016-01-19 11:32 ` [RFC PATCH 16/20] KEYS: Remove KEY_FLAG_TRUSTED and KEY_ALLOC_TRUSTED " David Howells
2016-01-19 11:32 ` [RFC PATCH 17/20] PKCS#7: Handle blacklisted certificates " David Howells
2016-01-19 11:32 ` [RFC PATCH 18/20] IMA: Use the system blacklist keyring " David Howells
2016-02-10 19:12 ` Mimi Zohar
2016-02-19 11:58 ` David Howells
2016-02-19 12:16 ` Mimi Zohar
2016-01-19 11:32 ` [RFC PATCH 19/20] certs: Add a secondary system keyring that can be added to dynamically " David Howells
2016-01-19 11:32 ` [RFC PATCH 20/20] IMA: Replace the .ima_mok keyring with the secondary system keyring " David Howells
2016-01-20 17:24 ` [RFC PATCH 00/20] KEYS: Restrict additions to 'trusted' keyrings " Petko Manolov
2016-02-03 15:47 ` David Howells
2016-01-20 18:57 ` Mimi Zohar
2016-02-03 15:56 ` David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1454932757.2648.143.camel@linux.vnet.ibm.com \
--to=zohar@linux.vnet.ibm.com \
--cc=dhowells@redhat.com \
--cc=keyrings@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=petkan@mip-labs.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.