]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Nov 2017 12:54:53 +0000 (13:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Nov 2017 12:54:53 +0000 (13:54 +0100)
added patches:
keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
rbd-use-gfp_noio-for-parent-stat-and-data-requests.patch

queue-3.18/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch [new file with mode: 0644]
queue-3.18/keys-trusted-sanitize-all-key-material.patch
queue-3.18/rbd-use-gfp_noio-for-parent-stat-and-data-requests.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch b/queue-3.18/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
new file mode 100644 (file)
index 0000000..8b88fa7
--- /dev/null
@@ -0,0 +1,69 @@
+From a3c812f7cfd80cf51e8f5b7034f7418f6beb56c1 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 2 Nov 2017 00:47:12 +0000
+Subject: KEYS: trusted: fix writing past end of buffer in trusted_read()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit a3c812f7cfd80cf51e8f5b7034f7418f6beb56c1 upstream.
+
+When calling keyctl_read() on a key of type "trusted", if the
+user-supplied buffer was too small, the kernel ignored the buffer length
+and just wrote past the end of the buffer, potentially corrupting
+userspace memory.  Fix it by instead returning the size required, as per
+the documentation for keyctl_read().
+
+We also don't even fill the buffer at all in this case, as this is
+slightly easier to implement than doing a short read, and either
+behavior appears to be permitted.  It also makes it match the behavior
+of the "encrypted" key type.
+
+Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
+Reported-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: <stable@vger.kernel.org> # v2.6.38+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/trusted.c |   23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+--- a/security/keys/trusted.c
++++ b/security/keys/trusted.c
+@@ -1065,20 +1065,21 @@ static long trusted_read(const struct ke
+       p = rcu_dereference_key(key);
+       if (!p)
+               return -EINVAL;
+-      if (!buffer || buflen <= 0)
+-              return 2 * p->blob_len;
+-      ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
+-      if (!ascii_buf)
+-              return -ENOMEM;
+-      bufp = ascii_buf;
+-      for (i = 0; i < p->blob_len; i++)
+-              bufp = hex_byte_pack(bufp, p->blob[i]);
+-      if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
++      if (buffer && buflen >= 2 * p->blob_len) {
++              ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
++              if (!ascii_buf)
++                      return -ENOMEM;
++
++              bufp = ascii_buf;
++              for (i = 0; i < p->blob_len; i++)
++                      bufp = hex_byte_pack(bufp, p->blob[i]);
++              if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) {
++                      kzfree(ascii_buf);
++                      return -EFAULT;
++              }
+               kzfree(ascii_buf);
+-              return -EFAULT;
+       }
+-      kzfree(ascii_buf);
+       return 2 * p->blob_len;
+ }
index 6d8dd11bcebcd2956264ddeb21582e09d101ed5f..855456b1c1ec0f4c9b1491264bfbf3024a74599f 100644 (file)
@@ -20,9 +20,10 @@ Signed-off-by: David Howells <dhowells@redhat.com>
 Signed-off-by: James Morris <james.l.morris@oracle.com>
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
+
 ---
- security/keys/trusted.c |   35 +++++++++++++++++------------------
- 1 file changed, 17 insertions(+), 18 deletions(-)
+ security/keys/trusted.c |   49 +++++++++++++++++++++---------------------------
+ 1 file changed, 22 insertions(+), 27 deletions(-)
 
 --- a/security/keys/trusted.c
 +++ b/security/keys/trusted.c
@@ -124,7 +125,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  }
  
  /*
-@@ -1018,7 +1017,7 @@ static int trusted_update(struct key *ke
+@@ -1018,9 +1017,10 @@ static int trusted_update(struct key *ke
        ret = datablob_parse(datablob, new_p, new_o);
        if (ret != Opt_update) {
                ret = -EINVAL;
@@ -132,8 +133,11 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 +              kzfree(new_p);
                goto out;
        }
++
        /* copy old key values, and reseal with new pcrs */
-@@ -1031,22 +1030,22 @@ static int trusted_update(struct key *ke
+       new_p->migratable = p->migratable;
+       new_p->key_len = p->key_len;
+@@ -1031,22 +1031,22 @@ static int trusted_update(struct key *ke
        ret = key_seal(new_p, new_o);
        if (ret < 0) {
                pr_info("trusted_key: key_seal failed (%d)\n", ret);
@@ -160,3 +164,32 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
        return ret;
  }
  
+@@ -1075,24 +1075,19 @@ static long trusted_read(const struct ke
+       for (i = 0; i < p->blob_len; i++)
+               bufp = hex_byte_pack(bufp, p->blob[i]);
+       if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
+-              kfree(ascii_buf);
++              kzfree(ascii_buf);
+               return -EFAULT;
+       }
+-      kfree(ascii_buf);
++      kzfree(ascii_buf);
+       return 2 * p->blob_len;
+ }
+ /*
+- * trusted_destroy - before freeing the key, clear the decrypted data
++ * trusted_destroy - clear and free the key's payload
+  */
+ static void trusted_destroy(struct key *key)
+ {
+-      struct trusted_key_payload *p = key->payload.data;
+-
+-      if (!p)
+-              return;
+-      memset(p->key, 0, p->key_len);
+-      kfree(key->payload.data);
++      kzfree(key->payload.data);
+ }
+ struct key_type key_type_trusted = {
diff --git a/queue-3.18/rbd-use-gfp_noio-for-parent-stat-and-data-requests.patch b/queue-3.18/rbd-use-gfp_noio-for-parent-stat-and-data-requests.patch
new file mode 100644 (file)
index 0000000..5ea4670
--- /dev/null
@@ -0,0 +1,44 @@
+From 1e37f2f84680fa7f8394fd444b6928e334495ccc Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Mon, 6 Nov 2017 11:33:36 +0100
+Subject: rbd: use GFP_NOIO for parent stat and data requests
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 1e37f2f84680fa7f8394fd444b6928e334495ccc upstream.
+
+rbd_img_obj_exists_submit() and rbd_img_obj_parent_read_full() are on
+the writeback path for cloned images -- we attempt a stat on the parent
+object to see if it exists and potentially read it in to call copyup.
+GFP_NOIO should be used instead of GFP_KERNEL here.
+
+Link: http://tracker.ceph.com/issues/22014
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: David Disseldorp <ddiss@suse.de>
+[idryomov@gmail.com: backport to < 4.9: context]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/rbd.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -2700,7 +2700,7 @@ static int rbd_img_obj_parent_read_full(
+        * from the parent.
+        */
+       page_count = (u32)calc_pages_for(0, length);
+-      pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
++      pages = ceph_alloc_page_vector(page_count, GFP_NOIO);
+       if (IS_ERR(pages)) {
+               result = PTR_ERR(pages);
+               pages = NULL;
+@@ -2827,7 +2827,7 @@ static int rbd_img_obj_exists_submit(str
+        */
+       size = sizeof (__le64) + sizeof (__le32) + sizeof (__le32);
+       page_count = (u32)calc_pages_for(0, size);
+-      pages = ceph_alloc_page_vector(page_count, GFP_KERNEL);
++      pages = ceph_alloc_page_vector(page_count, GFP_NOIO);
+       if (IS_ERR(pages))
+               return PTR_ERR(pages);
index b49349b2313ece8236c74ca4ed1c0b190884e3d8..1444e9cd9f5a186723b8f93c3a72e3b93f7ee5d2 100644 (file)
@@ -14,6 +14,7 @@ input-mpr121-handle-multiple-bits-change-of-status-register.patch
 input-mpr121-set-missing-event-capability.patch
 ib-ipoib-change-list_del-to-list_del_init-in-the-tx-object.patch
 keys-trusted-sanitize-all-key-material.patch
+keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
 crypto-x86-sha1-mb-fix-panic-due-to-unaligned-access.patch
 keys-fix-null-pointer-dereference-during-asn.1-parsing.patch
 arm-8720-1-ensure-dump_instr-checks-addr_limit.patch
@@ -22,3 +23,4 @@ alsa-seq-avoid-invalid-lockdep-class-warning.patch
 mips-micromips-fix-incorrect-mask-in-insn_table_mm.patch
 mips-fix-cm-region-target-definitions.patch
 mips-ar7-ensure-that-serial-ports-are-properly-set-up.patch
+rbd-use-gfp_noio-for-parent-stat-and-data-requests.patch