All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Eric Biggers <ebiggers@google.com>,
	David Howells <dhowells@redhat.com>
Subject: [PATCH 4.4 03/28] KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings
Date: Tue, 25 Apr 2017 16:08:34 +0100	[thread overview]
Message-ID: <20170425150814.847328457@linuxfoundation.org> (raw)
In-Reply-To: <20170425150814.719042460@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Biggers <ebiggers@google.com>

commit c9f838d104fed6f2f61d68164712e3204bf5271b upstream.

This fixes CVE-2017-7472.

Running the following program as an unprivileged user exhausts kernel
memory by leaking thread keyrings:

	#include <keyutils.h>

	int main()
	{
		for (;;)
			keyctl_set_reqkey_keyring(KEY_REQKEY_DEFL_THREAD_KEYRING);
	}

Fix it by only creating a new thread keyring if there wasn't one before.
To make things more consistent, make install_thread_keyring_to_cred()
and install_process_keyring_to_cred() both return 0 if the corresponding
keyring is already present.

Fixes: d84f4f992cbd ("CRED: Inaugurate COW credentials")
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 security/keys/keyctl.c       |   11 +++-------
 security/keys/process_keys.c |   44 ++++++++++++++++++++++++++-----------------
 2 files changed, 31 insertions(+), 24 deletions(-)

--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1228,8 +1228,8 @@ error:
  * Read or set the default keyring in which request_key() will cache keys and
  * return the old setting.
  *
- * If a process keyring is specified then this will be created if it doesn't
- * yet exist.  The old setting will be returned if successful.
+ * If a thread or process keyring is specified then it will be created if it
+ * doesn't yet exist.  The old setting will be returned if successful.
  */
 long keyctl_set_reqkey_keyring(int reqkey_defl)
 {
@@ -1254,11 +1254,8 @@ long keyctl_set_reqkey_keyring(int reqke
 
 	case KEY_REQKEY_DEFL_PROCESS_KEYRING:
 		ret = install_process_keyring_to_cred(new);
-		if (ret < 0) {
-			if (ret != -EEXIST)
-				goto error;
-			ret = 0;
-		}
+		if (ret < 0)
+			goto error;
 		goto set;
 
 	case KEY_REQKEY_DEFL_DEFAULT:
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -125,13 +125,18 @@ error:
 }
 
 /*
- * Install a fresh thread keyring directly to new credentials.  This keyring is
- * allowed to overrun the quota.
+ * Install a thread keyring to the given credentials struct if it didn't have
+ * one already.  This is allowed to overrun the quota.
+ *
+ * Return: 0 if a thread keyring is now present; -errno on failure.
  */
 int install_thread_keyring_to_cred(struct cred *new)
 {
 	struct key *keyring;
 
+	if (new->thread_keyring)
+		return 0;
+
 	keyring = keyring_alloc("_tid", new->uid, new->gid, new,
 				KEY_POS_ALL | KEY_USR_VIEW,
 				KEY_ALLOC_QUOTA_OVERRUN, NULL);
@@ -143,7 +148,9 @@ int install_thread_keyring_to_cred(struc
 }
 
 /*
- * Install a fresh thread keyring, discarding the old one.
+ * Install a thread keyring to the current task if it didn't have one already.
+ *
+ * Return: 0 if a thread keyring is now present; -errno on failure.
  */
 static int install_thread_keyring(void)
 {
@@ -154,8 +161,6 @@ static int install_thread_keyring(void)
 	if (!new)
 		return -ENOMEM;
 
-	BUG_ON(new->thread_keyring);
-
 	ret = install_thread_keyring_to_cred(new);
 	if (ret < 0) {
 		abort_creds(new);
@@ -166,17 +171,17 @@ static int install_thread_keyring(void)
 }
 
 /*
- * Install a process keyring directly to a credentials struct.
+ * Install a process keyring to the given credentials struct if it didn't have
+ * one already.  This is allowed to overrun the quota.
  *
- * Returns -EEXIST if there was already a process keyring, 0 if one installed,
- * and other value on any other error
+ * Return: 0 if a process keyring is now present; -errno on failure.
  */
 int install_process_keyring_to_cred(struct cred *new)
 {
 	struct key *keyring;
 
 	if (new->process_keyring)
-		return -EEXIST;
+		return 0;
 
 	keyring = keyring_alloc("_pid", new->uid, new->gid, new,
 				KEY_POS_ALL | KEY_USR_VIEW,
@@ -189,11 +194,9 @@ int install_process_keyring_to_cred(stru
 }
 
 /*
- * Make sure a process keyring is installed for the current process.  The
- * existing process keyring is not replaced.
+ * Install a process keyring to the current task if it didn't have one already.
  *
- * Returns 0 if there is a process keyring by the end of this function, some
- * error otherwise.
+ * Return: 0 if a process keyring is now present; -errno on failure.
  */
 static int install_process_keyring(void)
 {
@@ -207,14 +210,18 @@ static int install_process_keyring(void)
 	ret = install_process_keyring_to_cred(new);
 	if (ret < 0) {
 		abort_creds(new);
-		return ret != -EEXIST ? ret : 0;
+		return ret;
 	}
 
 	return commit_creds(new);
 }
 
 /*
- * Install a session keyring directly to a credentials struct.
+ * Install the given keyring as the session keyring of the given credentials
+ * struct, replacing the existing one if any.  If the given keyring is NULL,
+ * then install a new anonymous session keyring.
+ *
+ * Return: 0 on success; -errno on failure.
  */
 int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
 {
@@ -249,8 +256,11 @@ int install_session_keyring_to_cred(stru
 }
 
 /*
- * Install a session keyring, discarding the old one.  If a keyring is not
- * supplied, an empty one is invented.
+ * Install the given keyring as the session keyring of the current task,
+ * replacing the existing one if any.  If the given keyring is NULL, then
+ * install a new anonymous session keyring.
+ *
+ * Return: 0 on success; -errno on failure.
  */
 static int install_session_keyring(struct key *keyring)
 {

  parent reply	other threads:[~2017-04-25 15:31 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-25 15:08 [PATCH 4.4 00/28] 4.4.64-stable review Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 01/28] KEYS: Disallow keyrings beginning with . to be joined as session keyrings Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 02/28] KEYS: Change the name of the dead type to ".dead" to prevent user access Greg Kroah-Hartman
2017-04-25 15:08 ` Greg Kroah-Hartman [this message]
2017-04-25 15:08 ` [PATCH 4.4 04/28] tracing: Allocate the snapshot buffer before enabling probe Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 05/28] ring-buffer: Have ring_buffer_iter_empty() return true when empty Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 06/28] cifs: Do not send echoes before Negotiate is complete Greg Kroah-Hartman
2017-05-09 12:13   ` Ben Hutchings
2017-05-10  1:00     ` Pavel Shilovskiy
2017-05-25 16:59       ` Pavel Shilovskiy
2017-04-25 15:08 ` [PATCH 4.4 07/28] CIFS: remove bad_network_name flag Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 08/28] s390/mm: fix CMMA vs KSM vs others Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 09/28] Drivers: hv: dont leak memory in vmbus_establish_gpadl() Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 10/28] Drivers: hv: get rid of timeout in vmbus_open() Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 11/28] Drivers: hv: vmbus: Reduce the delay between retries in vmbus_post_msg() Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 12/28] VSOCK: Detach QP check should filter out non matching QPs Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 13/28] Input: elantech - add Fujitsu Lifebook E547 to force crc_enabled Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 14/28] ACPI / power: Avoid maybe-uninitialized warning Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 15/28] mmc: sdhci-esdhc-imx: increase the pad I/O drive strength for DDR50 card Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 16/28] mac80211: reject ToDS broadcast data frames Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 17/28] ubi/upd: Always flush after prepared for an update Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 18/28] powerpc/kprobe: Fix oops when kprobed on stdu instruction Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 19/28] x86/mce/AMD: Give a name to MCA bank 3 when accessed with legacy MSRs Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 20/28] kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 21/28] powerpc/64: Fix flush_(d|i)cache_range() called from modules Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 22/28] Tools: hv: kvp: ensure kvp device fd is closed on exec Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 23/28] Drivers: hv: balloon: keep track of where ha_region starts Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 24/28] Drivers: hv: balloon: account for gaps in hot add regions Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 25/28] hv: dont reset hv_context.tsc_page on crash Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 26/28] x86, pmem: fix broken __copy_user_nocache cache-bypass assumptions Greg Kroah-Hartman
2017-05-09 17:00   ` Ben Hutchings
2017-05-09 17:10     ` Dan Williams
2017-04-25 15:08 ` [PATCH 4.4 27/28] block: fix del_gendisk() vs blkdev_ioctl crash Greg Kroah-Hartman
2017-04-25 15:08 ` [PATCH 4.4 28/28] tipc: fix crash during node removal Greg Kroah-Hartman
2017-04-25 18:18 ` [PATCH 4.4 00/28] 4.4.64-stable review Shuah Khan
2017-04-26  8:32   ` Greg Kroah-Hartman
2017-04-25 21:26 ` Guenter Roeck
2017-04-26  2:27 ` Guenter Roeck
2017-04-26  8:31   ` Greg Kroah-Hartman
2017-04-26 13:10     ` Guenter Roeck
2017-04-26 13:11       ` Guenter Roeck
2017-04-26 14:39     ` Guenter Roeck
2017-04-26 15:48       ` Greg Kroah-Hartman

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=20170425150814.847328457@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=dhowells@redhat.com \
    --cc=ebiggers@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /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.