[Devel,RHEL7,COMMIT] ms/KVM: x86: Introduce segmented_write_std

Submitted by Konstantin Khorenko on Feb. 6, 2017, 1:08 p.m.


Message ID 201702061308.v16D8LmP032435@finist_cl7.x64_64.work.ct
State New
Series "ms/KVM: x86: Introduce segmented_write_std"
Headers show

Commit Message

Konstantin Khorenko Feb. 6, 2017, 1:08 p.m.
The commit is pushed to "branch-rh7-3.10.0-514.6.1.vz7.28.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.6.1.vz7.28.4
commit 6bf1f66dedf7b737c98d6f190a9e599200426b40
Author: Steve Rutherford <srutherford@google.com>
Date:   Mon Feb 6 17:08:21 2017 +0400

    ms/KVM: x86: Introduce segmented_write_std
    Introduces segemented_write_std.
    Switches from emulated reads/writes to standard read/writes in fxsave,
    fxrstor, sgdt, and sidt.  This fixes CVE-2017-2584, a longstanding
    kernel memory leak.
    Since commit 283c95d0e389 ("KVM: x86: emulate FXSAVE and FXRSTOR",
    2016-11-09), which is luckily not yet in any final release, this would
    also be an exploitable kernel memory *write*!
    there is no 283c95d0e389 (emulated fxrstor/fxsave) on the branch,
    so backported for sgdt/sidt only
    Reported-by: Dmitry Vyukov <dvyukov@google.com>
    Cc: stable@vger.kernel.org
    Fixes: 96051572c819194c37a8367624b285be10297eca
    Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Steve Rutherford <srutherford@google.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    (cherry picked from commit 129a72a0d3c8e139a04512325384fe5ac119e74d)
    Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
    Reviewed-by: Evgeny Yakovlev <eyakovlev@virtuozzo.com>
 arch/x86/kvm/emulate.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index f9da33c..574f824 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -811,6 +811,20 @@  static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
 	return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
+static int segmented_write_std(struct x86_emulate_ctxt *ctxt,
+			       struct segmented_address addr,
+			       void *data,
+			       unsigned int size)
+	int rc;
+	ulong linear;
+	rc = linearize(ctxt, addr, size, true, &linear);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception);
  * Prefetch the remaining bytes of the instruction without crossing page
  * boundary if they are not in fetch_cache yet.
@@ -3678,8 +3692,8 @@  static int emulate_store_desc_ptr(struct x86_emulate_ctxt *ctxt,
 	/* Disable writeback. */
 	ctxt->dst.type = OP_NONE;
-	return segmented_write(ctxt, ctxt->dst.addr.mem,
-			       &desc_ptr, 2 + ctxt->op_bytes);
+	return segmented_write_std(ctxt, ctxt->dst.addr.mem,
+				   &desc_ptr, 2 + ctxt->op_bytes);
 static int em_sgdt(struct x86_emulate_ctxt *ctxt)