]> xenbits.xensource.com Git - xen.git/commitdiff
x86/shadow: Avoid overflowing sh_ctxt->seg_reg[]
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 8 Sep 2016 12:29:05 +0000 (14:29 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 8 Sep 2016 12:29:05 +0000 (14:29 +0200)
hvm_get_seg_reg() does not perform a range check on its input segment, calls
hvm_get_segment_register() and writes straight into sh_ctxt->seg_reg[].

x86_seg_none is outside the bounds of sh_ctxt->seg_reg[], and will hit a BUG()
in {vmx,svm}_get_segment_register().

HVM guests running with shadow paging can end up performing a virtual to
linear translation with x86_seg_none.  This is used for addresses which are
already linear.  However, none of this is a legitimate pagetable update, so
fail the emulation in such a case.

This is XSA-187 / CVE-2016-7094.

Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Tim Deegan <tim@xen.org>
master commit: a9f3b3bad17d91e2067fc00d51b0302349570d08
master date: 2016-09-08 14:16:26 +0200

xen/arch/x86/mm/shadow/common.c

index 4e9206b8a9c99b5255740a00a6551f72d2b473a1..3820297f2d34c28b535c8fc2a5f957dd0601cd41 100644 (file)
@@ -137,9 +137,18 @@ static int hvm_translate_linear_addr(
     struct sh_emulate_ctxt *sh_ctxt,
     unsigned long *paddr)
 {
-    struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt);
+    struct segment_register *reg;
     int okay;
 
+    /*
+     * Can arrive here with non-user segments.  However, no such cirucmstance
+     * is part of a legitimate pagetable update, so fail the emulation.
+     */
+    if ( !is_x86_user_segment(seg) )
+        return X86EMUL_UNHANDLEABLE;
+
+    reg = hvm_get_seg_reg(seg, sh_ctxt);
+
     okay = hvm_virtual_to_linear_addr(
         seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr);