From: <gregkh@linuxfoundation.org>
To: zohar@linux.vnet.ibm.com, dhowells@redhat.com,
gregkh@linuxfoundation.org
Cc: <stable@vger.kernel.org>, <stable-commits@vger.kernel.org>
Subject: Patch "KEYS: prevent keys from being removed from specified keyrings" has been added to the 4.3-stable tree
Date: Wed, 20 Jan 2016 08:59:31 -0800 [thread overview]
Message-ID: <1453309171134160@kroah.com> (raw)
This is a note to let you know that I've just added the patch titled
KEYS: prevent keys from being removed from specified keyrings
to the 4.3-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
keys-prevent-keys-from-being-removed-from-specified-keyrings.patch
and it can be found in the queue-4.3 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
>From d3600bcf9d64d88dc1d189a754dcfab960ce751f Mon Sep 17 00:00:00 2001
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
Date: Tue, 10 Nov 2015 08:34:46 -0500
Subject: KEYS: prevent keys from being removed from specified keyrings
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
commit d3600bcf9d64d88dc1d189a754dcfab960ce751f upstream.
Userspace should not be allowed to remove keys from certain keyrings
(eg. blacklist), though the keys themselves can expire.
This patch defines a new key flag named KEY_FLAG_KEEP to prevent
userspace from being able to unlink, revoke, invalidate or timed
out a key on a keyring. When this flag is set on the keyring, all
keys subsequently added are flagged.
In addition, when this flag is set, the keyring itself can not be
cleared.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/key.h | 1
security/keys/key.c | 6 ++++-
security/keys/keyctl.c | 56 ++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 52 insertions(+), 11 deletions(-)
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -172,6 +172,7 @@ struct key {
#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 */
/* the key type and key description string
* - the desc is used to match a key against search criteria
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -429,8 +429,12 @@ static int __key_instantiate_and_link(st
awaken = 1;
/* and link it into the destination keyring */
- if (keyring)
+ if (keyring) {
+ if (test_bit(KEY_FLAG_KEEP, &keyring->flags))
+ set_bit(KEY_FLAG_KEEP, &key->flags);
+
__key_link(key, _edit);
+ }
/* disable the authorisation key */
if (authkey)
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -364,11 +364,14 @@ error:
* and any links to the key will be automatically garbage collected after a
* certain amount of time (/proc/sys/kernel/keys/gc_delay).
*
+ * Keys with KEY_FLAG_KEEP set should not be revoked.
+ *
* If successful, 0 is returned.
*/
long keyctl_revoke_key(key_serial_t id)
{
key_ref_t key_ref;
+ struct key *key;
long ret;
key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE);
@@ -383,8 +386,13 @@ long keyctl_revoke_key(key_serial_t id)
}
}
- key_revoke(key_ref_to_ptr(key_ref));
- ret = 0;
+ key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_KEEP, &key->flags))
+ return -EPERM;
+ else {
+ key_revoke(key);
+ ret = 0;
+ }
key_ref_put(key_ref);
error:
@@ -398,11 +406,14 @@ error:
* The key and any links to the key will be automatically garbage collected
* immediately.
*
+ * Keys with KEY_FLAG_KEEP set should not be invalidated.
+ *
* If successful, 0 is returned.
*/
long keyctl_invalidate_key(key_serial_t id)
{
key_ref_t key_ref;
+ struct key *key;
long ret;
kenter("%d", id);
@@ -426,8 +437,13 @@ long keyctl_invalidate_key(key_serial_t
}
invalidate:
- key_invalidate(key_ref_to_ptr(key_ref));
- ret = 0;
+ key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_KEEP, &key->flags))
+ ret = -EPERM;
+ else {
+ key_invalidate(key);
+ ret = 0;
+ }
error_put:
key_ref_put(key_ref);
error:
@@ -439,12 +455,13 @@ error:
* Clear the specified keyring, creating an empty process keyring if one of the
* special keyring IDs is used.
*
- * The keyring must grant the caller Write permission for this to work. If
- * successful, 0 will be returned.
+ * The keyring must grant the caller Write permission and not have
+ * KEY_FLAG_KEEP set for this to work. If successful, 0 will be returned.
*/
long keyctl_keyring_clear(key_serial_t ringid)
{
key_ref_t keyring_ref;
+ struct key *keyring;
long ret;
keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
@@ -466,7 +483,11 @@ long keyctl_keyring_clear(key_serial_t r
}
clear:
- ret = keyring_clear(key_ref_to_ptr(keyring_ref));
+ keyring = key_ref_to_ptr(keyring_ref);
+ if (test_bit(KEY_FLAG_KEEP, &keyring->flags))
+ ret = -EPERM;
+ else
+ ret = keyring_clear(keyring);
error_put:
key_ref_put(keyring_ref);
error:
@@ -517,11 +538,14 @@ error:
* itself need not grant the caller anything. If the last link to a key is
* removed then that key will be scheduled for destruction.
*
+ * Keys or keyrings with KEY_FLAG_KEEP set should not be unlinked.
+ *
* If successful, 0 will be returned.
*/
long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
{
key_ref_t keyring_ref, key_ref;
+ struct key *keyring, *key;
long ret;
keyring_ref = lookup_user_key(ringid, 0, KEY_NEED_WRITE);
@@ -536,7 +560,13 @@ long keyctl_keyring_unlink(key_serial_t
goto error2;
}
- ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
+ keyring = key_ref_to_ptr(keyring_ref);
+ key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_KEEP, &keyring->flags) &&
+ test_bit(KEY_FLAG_KEEP, &key->flags))
+ ret = -EPERM;
+ else
+ ret = key_unlink(keyring, key);
key_ref_put(key_ref);
error2:
@@ -1295,6 +1325,8 @@ error:
* the current time. The key and any links to the key will be automatically
* garbage collected after the timeout expires.
*
+ * Keys with KEY_FLAG_KEEP set should not be timed out.
+ *
* If successful, 0 is returned.
*/
long keyctl_set_timeout(key_serial_t id, unsigned timeout)
@@ -1326,10 +1358,14 @@ long keyctl_set_timeout(key_serial_t id,
okay:
key = key_ref_to_ptr(key_ref);
- key_set_timeout(key, timeout);
+ if (test_bit(KEY_FLAG_KEEP, &key->flags))
+ ret = -EPERM;
+ else {
+ key_set_timeout(key, timeout);
+ ret = 0;
+ }
key_put(key);
- ret = 0;
error:
return ret;
}
Patches currently in stable-queue which might be from zohar@linux.vnet.ibm.com are
queue-4.3/tpm-tpm_tis-fix-tpm_tis-acpi-detection-issue-with-tpm-2.0.patch
queue-4.3/keys-refcount-bug-fix.patch
queue-4.3/keys-prevent-keys-from-being-removed-from-specified-keyrings.patch
reply other threads:[~2016-01-20 16:59 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=1453309171134160@kroah.com \
--to=gregkh@linuxfoundation.org \
--cc=dhowells@redhat.com \
--cc=stable-commits@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=zohar@linux.vnet.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).