]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Jun 2018 12:16:13 +0000 (14:16 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Jun 2018 12:16:13 +0000 (14:16 +0200)
added patches:
kvm-x86-use-correct-privilege-level-for-sgdt-sidt-fxsave-fxrstor-access.patch

queue-4.17/kvm-x86-use-correct-privilege-level-for-sgdt-sidt-fxsave-fxrstor-access.patch [new file with mode: 0644]
queue-4.17/series

diff --git a/queue-4.17/kvm-x86-use-correct-privilege-level-for-sgdt-sidt-fxsave-fxrstor-access.patch b/queue-4.17/kvm-x86-use-correct-privilege-level-for-sgdt-sidt-fxsave-fxrstor-access.patch
new file mode 100644 (file)
index 0000000..2d9f66a
--- /dev/null
@@ -0,0 +1,160 @@
+From 3c9fa24ca7c9c47605672916491f79e8ccacb9e6 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Wed, 6 Jun 2018 17:38:09 +0200
+Subject: kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit 3c9fa24ca7c9c47605672916491f79e8ccacb9e6 upstream.
+
+The functions that were used in the emulation of fxrstor, fxsave, sgdt and
+sidt were originally meant for task switching, and as such they did not
+check privilege levels.  This is very bad when the same functions are used
+in the emulation of unprivileged instructions.  This is CVE-2018-10853.
+
+The obvious fix is to add a new argument to ops->read_std and ops->write_std,
+which decides whether the access is a "system" access or should use the
+processor's CPL.
+
+Fixes: 129a72a0d3c8 ("KVM: x86: Introduce segmented_write_std", 2017-01-12)
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/kvm_emulate.h |    6 ++++--
+ arch/x86/kvm/emulate.c             |   12 ++++++------
+ arch/x86/kvm/x86.c                 |   22 ++++++++++++++++------
+ 3 files changed, 26 insertions(+), 14 deletions(-)
+
+--- a/arch/x86/include/asm/kvm_emulate.h
++++ b/arch/x86/include/asm/kvm_emulate.h
+@@ -107,11 +107,12 @@ struct x86_emulate_ops {
+        *  @addr:  [IN ] Linear address from which to read.
+        *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
+        *  @bytes: [IN ] Number of bytes to read from memory.
++       *  @system:[IN ] Whether the access is forced to be at CPL0.
+        */
+       int (*read_std)(struct x86_emulate_ctxt *ctxt,
+                       unsigned long addr, void *val,
+                       unsigned int bytes,
+-                      struct x86_exception *fault);
++                      struct x86_exception *fault, bool system);
+       /*
+        * read_phys: Read bytes of standard (non-emulated/special) memory.
+@@ -129,10 +130,11 @@ struct x86_emulate_ops {
+        *  @addr:  [IN ] Linear address to which to write.
+        *  @val:   [OUT] Value write to memory, zero-extended to 'u_long'.
+        *  @bytes: [IN ] Number of bytes to write to memory.
++       *  @system:[IN ] Whether the access is forced to be at CPL0.
+        */
+       int (*write_std)(struct x86_emulate_ctxt *ctxt,
+                        unsigned long addr, void *val, unsigned int bytes,
+-                       struct x86_exception *fault);
++                       struct x86_exception *fault, bool system);
+       /*
+        * fetch: Read bytes of standard (non-emulated/special) memory.
+        *        Used for instruction fetch.
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -815,14 +815,14 @@ static inline int jmp_rel(struct x86_emu
+ static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear,
+                             void *data, unsigned size)
+ {
+-      return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
++      return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, true);
+ }
+ static int linear_write_system(struct x86_emulate_ctxt *ctxt,
+                              ulong linear, void *data,
+                              unsigned int size)
+ {
+-      return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception);
++      return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, true);
+ }
+ static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
+@@ -836,7 +836,7 @@ static int segmented_read_std(struct x86
+       rc = linearize(ctxt, addr, size, false, &linear);
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+-      return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
++      return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, false);
+ }
+ static int segmented_write_std(struct x86_emulate_ctxt *ctxt,
+@@ -850,7 +850,7 @@ static int segmented_write_std(struct x8
+       rc = linearize(ctxt, addr, size, true, &linear);
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+-      return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception);
++      return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, false);
+ }
+ /*
+@@ -2928,12 +2928,12 @@ static bool emulator_io_port_access_allo
+ #ifdef CONFIG_X86_64
+       base |= ((u64)base3) << 32;
+ #endif
+-      r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL);
++      r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true);
+       if (r != X86EMUL_CONTINUE)
+               return false;
+       if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg))
+               return false;
+-      r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL);
++      r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, true);
+       if (r != X86EMUL_CONTINUE)
+               return false;
+       if ((perm >> bit_idx) & mask)
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -4800,10 +4800,15 @@ EXPORT_SYMBOL_GPL(kvm_read_guest_virt);
+ static int emulator_read_std(struct x86_emulate_ctxt *ctxt,
+                            gva_t addr, void *val, unsigned int bytes,
+-                           struct x86_exception *exception)
++                           struct x86_exception *exception, bool system)
+ {
+       struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+-      return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception);
++      u32 access = 0;
++
++      if (!system && kvm_x86_ops->get_cpl(vcpu) == 3)
++              access |= PFERR_USER_MASK;
++
++      return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception);
+ }
+ static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt,
+@@ -4847,12 +4852,17 @@ out:
+ }
+ static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val,
+-                            unsigned int bytes, struct x86_exception *exception)
++                            unsigned int bytes, struct x86_exception *exception,
++                            bool system)
+ {
+       struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
++      u32 access = PFERR_WRITE_MASK;
++
++      if (!system && kvm_x86_ops->get_cpl(vcpu) == 3)
++              access |= PFERR_USER_MASK;
+       return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
+-                                         PFERR_WRITE_MASK, exception);
++                                         access, exception);
+ }
+ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val,
+@@ -4871,8 +4881,8 @@ int handle_ud(struct kvm_vcpu *vcpu)
+       struct x86_exception e;
+       if (force_emulation_prefix &&
+-          kvm_read_guest_virt(&vcpu->arch.emulate_ctxt,
+-                              kvm_get_linear_rip(vcpu), sig, sizeof(sig), &e) == 0 &&
++          kvm_read_guest_virt(vcpu, kvm_get_linear_rip(vcpu),
++                              sig, sizeof(sig), &e) == 0 &&
+           memcmp(sig, "\xf\xbkvm", sizeof(sig)) == 0) {
+               kvm_rip_write(vcpu, kvm_rip_read(vcpu) + sizeof(sig));
+               emul_type = 0;
index 7b42a8b8b430df13ed285cf2f02c389b78990874..9d46be2ac7b9c4aeaddc510fa5aa37c9285245a0 100644 (file)
@@ -5,6 +5,7 @@ kvm-x86-introduce-linear_-read-write-_system.patch
 kvm-fix-typo-in-flag-name.patch
 kvm-nvmx-enforce-cpl-0-for-vmx-instructions.patch
 kvm-x86-pass-kvm_vcpu-to-kvm_read_guest_virt-and-kvm_write_guest_virt_system.patch
+kvm-x86-use-correct-privilege-level-for-sgdt-sidt-fxsave-fxrstor-access.patch
 staging-android-ion-switch-to-pr_warn_once-in-ion_buffer_destroy.patch
 nfc-pn533-don-t-send-usb-data-off-of-the-stack.patch
 usbip-vhci_sysfs-fix-potential-spectre-v1.patch