]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Apr 2020 14:41:49 +0000 (16:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Apr 2020 14:41:49 +0000 (16:41 +0200)
added patches:
crypto-mxs-dcp-fix-scatterlist-linearization-for-hash.patch
kvm-x86-allocate-new-rmap-and-large-page-tracking-when-moving-memslot.patch

queue-4.4/crypto-mxs-dcp-fix-scatterlist-linearization-for-hash.patch [new file with mode: 0644]
queue-4.4/kvm-x86-allocate-new-rmap-and-large-page-tracking-when-moving-memslot.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/crypto-mxs-dcp-fix-scatterlist-linearization-for-hash.patch b/queue-4.4/crypto-mxs-dcp-fix-scatterlist-linearization-for-hash.patch
new file mode 100644 (file)
index 0000000..223fb28
--- /dev/null
@@ -0,0 +1,113 @@
+From fa03481b6e2e82355c46644147b614f18c7a8161 Mon Sep 17 00:00:00 2001
+From: Rosioru Dragos <dragos.rosioru@nxp.com>
+Date: Tue, 25 Feb 2020 17:05:52 +0200
+Subject: crypto: mxs-dcp - fix scatterlist linearization for hash
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rosioru Dragos <dragos.rosioru@nxp.com>
+
+commit fa03481b6e2e82355c46644147b614f18c7a8161 upstream.
+
+The incorrect traversal of the scatterlist, during the linearization phase
+lead to computing the hash value of the wrong input buffer.
+New implementation uses scatterwalk_map_and_copy()
+to address this issue.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 15b59e7c3733 ("crypto: mxs - Add Freescale MXS DCP driver")
+Signed-off-by: Rosioru Dragos <dragos.rosioru@nxp.com>
+Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/mxs-dcp.c |   54 ++++++++++++++++++++++-------------------------
+ 1 file changed, 26 insertions(+), 28 deletions(-)
+
+--- a/drivers/crypto/mxs-dcp.c
++++ b/drivers/crypto/mxs-dcp.c
+@@ -25,6 +25,7 @@
+ #include <crypto/aes.h>
+ #include <crypto/sha.h>
+ #include <crypto/internal/hash.h>
++#include <crypto/scatterwalk.h>
+ #define DCP_MAX_CHANS 4
+ #define DCP_BUF_SZ    PAGE_SIZE
+@@ -626,49 +627,46 @@ static int dcp_sha_req_to_buf(struct cry
+       struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm);
+       struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req);
+       struct hash_alg_common *halg = crypto_hash_alg_common(tfm);
+-      const int nents = sg_nents(req->src);
+       uint8_t *in_buf = sdcp->coh->sha_in_buf;
+       uint8_t *out_buf = sdcp->coh->sha_out_buf;
+-      uint8_t *src_buf;
+-
+       struct scatterlist *src;
+-      unsigned int i, len, clen;
++      unsigned int i, len, clen, oft = 0;
+       int ret;
+       int fin = rctx->fini;
+       if (fin)
+               rctx->fini = 0;
+-      for_each_sg(req->src, src, nents, i) {
+-              src_buf = sg_virt(src);
+-              len = sg_dma_len(src);
++      src = req->src;
++      len = req->nbytes;
+-              do {
+-                      if (actx->fill + len > DCP_BUF_SZ)
+-                              clen = DCP_BUF_SZ - actx->fill;
+-                      else
+-                              clen = len;
++      while (len) {
++              if (actx->fill + len > DCP_BUF_SZ)
++                      clen = DCP_BUF_SZ - actx->fill;
++              else
++                      clen = len;
+-                      memcpy(in_buf + actx->fill, src_buf, clen);
+-                      len -= clen;
+-                      src_buf += clen;
+-                      actx->fill += clen;
++              scatterwalk_map_and_copy(in_buf + actx->fill, src, oft, clen,
++                                       0);
+-                      /*
+-                       * If we filled the buffer and still have some
+-                       * more data, submit the buffer.
+-                       */
+-                      if (len && actx->fill == DCP_BUF_SZ) {
+-                              ret = mxs_dcp_run_sha(req);
+-                              if (ret)
+-                                      return ret;
+-                              actx->fill = 0;
+-                              rctx->init = 0;
+-                      }
+-              } while (len);
++              len -= clen;
++              oft += clen;
++              actx->fill += clen;
++
++              /*
++               * If we filled the buffer and still have some
++               * more data, submit the buffer.
++               */
++              if (len && actx->fill == DCP_BUF_SZ) {
++                      ret = mxs_dcp_run_sha(req);
++                      if (ret)
++                              return ret;
++                      actx->fill = 0;
++                      rctx->init = 0;
++              }
+       }
+       if (fin) {
diff --git a/queue-4.4/kvm-x86-allocate-new-rmap-and-large-page-tracking-when-moving-memslot.patch b/queue-4.4/kvm-x86-allocate-new-rmap-and-large-page-tracking-when-moving-memslot.patch
new file mode 100644 (file)
index 0000000..a5e841a
--- /dev/null
@@ -0,0 +1,102 @@
+From edd4fa37baa6ee8e44dc65523b27bd6fe44c94de Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+Date: Tue, 18 Feb 2020 13:07:15 -0800
+Subject: KVM: x86: Allocate new rmap and large page tracking when moving memslot
+
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+
+commit edd4fa37baa6ee8e44dc65523b27bd6fe44c94de upstream.
+
+Reallocate a rmap array and recalcuate large page compatibility when
+moving an existing memslot to correctly handle the alignment properties
+of the new memslot.  The number of rmap entries required at each level
+is dependent on the alignment of the memslot's base gfn with respect to
+that level, e.g. moving a large-page aligned memslot so that it becomes
+unaligned will increase the number of rmap entries needed at the now
+unaligned level.
+
+Not updating the rmap array is the most obvious bug, as KVM accesses
+garbage data beyond the end of the rmap.  KVM interprets the bad data as
+pointers, leading to non-canonical #GPs, unexpected #PFs, etc...
+
+  general protection fault: 0000 [#1] SMP
+  CPU: 0 PID: 1909 Comm: move_memory_reg Not tainted 5.4.0-rc7+ #139
+  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+  RIP: 0010:rmap_get_first+0x37/0x50 [kvm]
+  Code: <48> 8b 3b 48 85 ff 74 ec e8 6c f4 ff ff 85 c0 74 e3 48 89 d8 5b c3
+  RSP: 0018:ffffc9000021bbc8 EFLAGS: 00010246
+  RAX: ffff00617461642e RBX: ffff00617461642e RCX: 0000000000000012
+  RDX: ffff88827400f568 RSI: ffffc9000021bbe0 RDI: ffff88827400f570
+  RBP: 0010000000000000 R08: ffffc9000021bd00 R09: ffffc9000021bda8
+  R10: ffffc9000021bc48 R11: 0000000000000000 R12: 0030000000000000
+  R13: 0000000000000000 R14: ffff88827427d700 R15: ffffc9000021bce8
+  FS:  00007f7eda014700(0000) GS:ffff888277a00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00007f7ed9216ff8 CR3: 0000000274391003 CR4: 0000000000162eb0
+  Call Trace:
+   kvm_mmu_slot_set_dirty+0xa1/0x150 [kvm]
+   __kvm_set_memory_region.part.64+0x559/0x960 [kvm]
+   kvm_set_memory_region+0x45/0x60 [kvm]
+   kvm_vm_ioctl+0x30f/0x920 [kvm]
+   do_vfs_ioctl+0xa1/0x620
+   ksys_ioctl+0x66/0x70
+   __x64_sys_ioctl+0x16/0x20
+   do_syscall_64+0x4c/0x170
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+  RIP: 0033:0x7f7ed9911f47
+  Code: <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 21 6f 2c 00 f7 d8 64 89 01 48
+  RSP: 002b:00007ffc00937498 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+  RAX: ffffffffffffffda RBX: 0000000001ab0010 RCX: 00007f7ed9911f47
+  RDX: 0000000001ab1350 RSI: 000000004020ae46 RDI: 0000000000000004
+  RBP: 000000000000000a R08: 0000000000000000 R09: 00007f7ed9214700
+  R10: 00007f7ed92149d0 R11: 0000000000000246 R12: 00000000bffff000
+  R13: 0000000000000003 R14: 00007f7ed9215000 R15: 0000000000000000
+  Modules linked in: kvm_intel kvm irqbypass
+  ---[ end trace 0c5f570b3358ca89 ]---
+
+The disallow_lpage tracking is more subtle.  Failure to update results
+in KVM creating large pages when it shouldn't, either due to stale data
+or again due to indexing beyond the end of the metadata arrays, which
+can lead to memory corruption and/or leaking data to guest/userspace.
+
+Note, the arrays for the old memslot are freed by the unconditional call
+to kvm_free_memslot() in __kvm_set_memory_region().
+
+Fixes: 05da45583de9b ("KVM: MMU: large page support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/x86.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -7982,6 +7982,13 @@ int kvm_arch_create_memslot(struct kvm *
+ {
+       int i;
++      /*
++       * Clear out the previous array pointers for the KVM_MR_MOVE case.  The
++       * old arrays will be freed by __kvm_set_memory_region() if installing
++       * the new memslot is successful.
++       */
++      memset(&slot->arch, 0, sizeof(slot->arch));
++
+       for (i = 0; i < KVM_NR_PAGE_SIZES; ++i) {
+               unsigned long ugfn;
+               int lpages;
+@@ -8050,6 +8057,10 @@ int kvm_arch_prepare_memory_region(struc
+                               const struct kvm_userspace_memory_region *mem,
+                               enum kvm_mr_change change)
+ {
++      if (change == KVM_MR_MOVE)
++              return kvm_arch_create_memslot(kvm, memslot,
++                                             mem->memory_size >> PAGE_SHIFT);
++
+       return 0;
+ }
index 75a865cc980f6072913b2cc80113ff16f3310d38..11904d36b0b6b82fb21c927a7220bccae357c3e6 100644 (file)
@@ -30,3 +30,5 @@ mips-octeon-irq-fix-potential-null-pointer-dereference.patch
 ath9k-handle-txpower-changes-even-when-tpc-is-disabled.patch
 signal-extend-exec_id-to-64bits.patch
 x86-entry-32-add-missing-asm_clac-to-general_protection-entry.patch
+kvm-x86-allocate-new-rmap-and-large-page-tracking-when-moving-memslot.patch
+crypto-mxs-dcp-fix-scatterlist-linearization-for-hash.patch