]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.18.81/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
Linux 4.14.114
[thirdparty/kernel/stable-queue.git] / releases / 3.18.81 / keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
CommitLineData
1218db86
GKH
1From a3c812f7cfd80cf51e8f5b7034f7418f6beb56c1 Mon Sep 17 00:00:00 2001
2From: Eric Biggers <ebiggers@google.com>
3Date: Thu, 2 Nov 2017 00:47:12 +0000
4Subject: KEYS: trusted: fix writing past end of buffer in trusted_read()
5
6From: Eric Biggers <ebiggers@google.com>
7
8commit a3c812f7cfd80cf51e8f5b7034f7418f6beb56c1 upstream.
9
10When calling keyctl_read() on a key of type "trusted", if the
11user-supplied buffer was too small, the kernel ignored the buffer length
12and just wrote past the end of the buffer, potentially corrupting
13userspace memory. Fix it by instead returning the size required, as per
14the documentation for keyctl_read().
15
16We also don't even fill the buffer at all in this case, as this is
17slightly easier to implement than doing a short read, and either
18behavior appears to be permitted. It also makes it match the behavior
19of the "encrypted" key type.
20
21Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
22Reported-by: Ben Hutchings <ben@decadent.org.uk>
23Cc: <stable@vger.kernel.org> # v2.6.38+
24Signed-off-by: Eric Biggers <ebiggers@google.com>
25Signed-off-by: David Howells <dhowells@redhat.com>
26Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
27Reviewed-by: James Morris <james.l.morris@oracle.com>
28Signed-off-by: James Morris <james.l.morris@oracle.com>
29Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30
31---
32 security/keys/trusted.c | 23 ++++++++++++-----------
33 1 file changed, 12 insertions(+), 11 deletions(-)
34
35--- a/security/keys/trusted.c
36+++ b/security/keys/trusted.c
37@@ -1065,20 +1065,21 @@ static long trusted_read(const struct ke
38 p = rcu_dereference_key(key);
39 if (!p)
40 return -EINVAL;
41- if (!buffer || buflen <= 0)
42- return 2 * p->blob_len;
43- ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
44- if (!ascii_buf)
45- return -ENOMEM;
46
47- bufp = ascii_buf;
48- for (i = 0; i < p->blob_len; i++)
49- bufp = hex_byte_pack(bufp, p->blob[i]);
50- if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
51+ if (buffer && buflen >= 2 * p->blob_len) {
52+ ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
53+ if (!ascii_buf)
54+ return -ENOMEM;
55+
56+ bufp = ascii_buf;
57+ for (i = 0; i < p->blob_len; i++)
58+ bufp = hex_byte_pack(bufp, p->blob[i]);
59+ if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) {
60+ kzfree(ascii_buf);
61+ return -EFAULT;
62+ }
63 kzfree(ascii_buf);
64- return -EFAULT;
65 }
66- kzfree(ascii_buf);
67 return 2 * p->blob_len;
68 }
69