stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KEYS: return full count in keyring_read() if buffer is too small
@ 2017-10-26 20:56 Eric Biggers
  2017-10-27  8:04 ` James Morris
  0 siblings, 1 reply; 2+ messages in thread
From: Eric Biggers @ 2017-10-26 20:56 UTC (permalink / raw)
  To: keyrings; +Cc: David Howells, Ben Hutchings, Xiao Yang, Eric Biggers, stable

From: Eric Biggers <ebiggers@google.com>

Commit e645016abc80 ("KEYS: fix writing past end of user-supplied buffer
in keyring_read()") made keyring_read() stop corrupting userspace memory
when the user-supplied buffer is too small.  However it also made the
return value in that case be the short buffer size rather than the size
required, yet keyctl_read() is actually documented to return the size
required.  Therefore, switch it over to the documented behavior.

Note that for now we continue to have it fill the short buffer, since it
did that before (pre-v3.13) and dump_key_tree_aux() in keyutils arguably
relies on it.

Fixes: e645016abc80 ("KEYS: fix writing past end of user-supplied buffer in keyring_read()")
Reported-by: Ben Hutchings <ben@decadent.org.uk>
Cc: <stable@vger.kernel.org> # v3.13+
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 security/keys/keyring.c | 39 +++++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index a7e51f793867..36f842ec87f0 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -459,34 +459,33 @@ static long keyring_read(const struct key *keyring,
 			 char __user *buffer, size_t buflen)
 {
 	struct keyring_read_iterator_context ctx;
-	unsigned long nr_keys;
-	int ret;
+	long ret;
 
 	kenter("{%d},,%zu", key_serial(keyring), buflen);
 
 	if (buflen & (sizeof(key_serial_t) - 1))
 		return -EINVAL;
 
-	nr_keys = keyring->keys.nr_leaves_on_tree;
-	if (nr_keys == 0)
-		return 0;
-
-	/* Calculate how much data we could return */
-	if (!buffer || !buflen)
-		return nr_keys * sizeof(key_serial_t);
-
-	/* Copy the IDs of the subscribed keys into the buffer */
-	ctx.buffer = (key_serial_t __user *)buffer;
-	ctx.buflen = buflen;
-	ctx.count = 0;
-	ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx);
-	if (ret < 0) {
-		kleave(" = %d [iterate]", ret);
-		return ret;
+	/* Copy as many key IDs as fit into the buffer */
+	if (buffer && buflen) {
+		ctx.buffer = (key_serial_t __user *)buffer;
+		ctx.buflen = buflen;
+		ctx.count = 0;
+		ret = assoc_array_iterate(&keyring->keys,
+					  keyring_read_iterator, &ctx);
+		if (ret < 0) {
+			kleave(" = %ld [iterate]", ret);
+			return ret;
+		}
 	}
 
-	kleave(" = %zu [ok]", ctx.count);
-	return ctx.count;
+	/* Return the size of the buffer needed */
+	ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t);
+	if (ret <= buflen)
+		kleave("= %ld [ok]", ret);
+	else
+		kleave("= %ld [buffer too small]", ret);
+	return ret;
 }
 
 /*
-- 
2.15.0.rc2.357.g7e34df9404-goog

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] KEYS: return full count in keyring_read() if buffer is too small
  2017-10-26 20:56 [PATCH] KEYS: return full count in keyring_read() if buffer is too small Eric Biggers
@ 2017-10-27  8:04 ` James Morris
  0 siblings, 0 replies; 2+ messages in thread
From: James Morris @ 2017-10-27  8:04 UTC (permalink / raw)
  To: Eric Biggers
  Cc: keyrings, David Howells, Ben Hutchings, Xiao Yang, Eric Biggers,
	stable

On Thu, 26 Oct 2017, Eric Biggers wrote:

> From: Eric Biggers <ebiggers@google.com>
> 
> Commit e645016abc80 ("KEYS: fix writing past end of user-supplied buffer
> in keyring_read()") made keyring_read() stop corrupting userspace memory
> when the user-supplied buffer is too small.  However it also made the
> return value in that case be the short buffer size rather than the size
> required, yet keyctl_read() is actually documented to return the size
> required.  Therefore, switch it over to the documented behavior.
> 
> Note that for now we continue to have it fill the short buffer, since it
> did that before (pre-v3.13) and dump_key_tree_aux() in keyutils arguably
> relies on it.
> 
> Fixes: e645016abc80 ("KEYS: fix writing past end of user-supplied buffer in keyring_read()")
> Reported-by: Ben Hutchings <ben@decadent.org.uk>
> Cc: <stable@vger.kernel.org> # v3.13+
> Signed-off-by: Eric Biggers <ebiggers@google.com>


Reviewed-by: James Morris <james.l.morris@oracle.com>

-- 
James Morris
<james.l.morris@oracle.com>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-10-27  8:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-26 20:56 [PATCH] KEYS: return full count in keyring_read() if buffer is too small Eric Biggers
2017-10-27  8:04 ` James Morris

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).