[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86_64: Be more careful in emulating 32-bit call gates.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1207644417 -3600
# Node ID 324f772239a7062bed404fac02adefa817bf10ca
# Parent  146f214a0e63cd46492b1e4748922bad2ce85af8
x86_64: Be more careful in emulating 32-bit call gates.

An assertion could legitimately fire.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/traps.c |   28 ++++++++++++++++------------
 1 files changed, 16 insertions(+), 12 deletions(-)

diff -r 146f214a0e63 -r 324f772239a7 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Mon Apr 07 15:02:47 2008 +0100
+++ b/xen/arch/x86/traps.c      Tue Apr 08 09:46:57 2008 +0100
@@ -1305,23 +1305,24 @@ static int read_gate_descriptor(unsigned
     const struct desc_struct *pdesc;
 
 
-    pdesc = (const struct desc_struct *)(!(gate_sel & 4) ?
-                                         GDT_VIRT_START(v) :
-                                         LDT_VIRT_START(v))
-            + (gate_sel >> 3);
-    if ( gate_sel < 4 ||
-         (gate_sel >= FIRST_RESERVED_GDT_BYTE && !(gate_sel & 4)) ||
+    pdesc = (const struct desc_struct *)
+        (!(gate_sel & 4) ? GDT_VIRT_START(v) : LDT_VIRT_START(v))
+        + (gate_sel >> 3);
+    if ( (gate_sel < 4) ||
+         ((gate_sel >= FIRST_RESERVED_GDT_BYTE) && !(gate_sel & 4)) ||
          __get_user(desc, pdesc) )
         return 0;
 
     *sel = (desc.a >> 16) & 0x0000fffc;
     *off = (desc.a & 0x0000ffff) | (desc.b & 0xffff0000);
     *ar = desc.b & 0x0000ffff;
+
     /*
      * check_descriptor() clears the DPL field and stores the
      * guest requested DPL in the selector's RPL field.
      */
-    ASSERT(!(*ar & _SEGMENT_DPL));
+    if ( *ar & _SEGMENT_DPL )
+        return 0;
     *ar |= (desc.a >> (16 - 13)) & _SEGMENT_DPL;
 
     if ( !is_pv_32bit_vcpu(v) )
@@ -2137,8 +2138,8 @@ static void emulate_gate_op(struct cpu_u
 
     /* Check whether this fault is due to the use of a call gate. */
     if ( !read_gate_descriptor(regs->error_code, v, &sel, &off, &ar) ||
-         ((ar >> 13) & 3) < (regs->cs & 3) ||
-         (ar & _SEGMENT_TYPE) != 0xc00 )
+         (((ar >> 13) & 3) < (regs->cs & 3)) ||
+         ((ar & _SEGMENT_TYPE) != 0xc00) )
     {
         do_guest_trap(TRAP_gp_fault, regs, 1);
         return;
@@ -2232,15 +2233,18 @@ static void emulate_gate_op(struct cpu_u
                     {
                         if ( (modrm & 7) == 4 )
                         {
-                            unsigned int sib = insn_fetch(u8, base, eip, 
limit);
+                            unsigned int sib;
+                            sib = insn_fetch(u8, base, eip, limit);
 
                             modrm = (modrm & ~7) | (sib & 7);
                             if ( (sib >>= 3) != 4 )
-                                opnd_off = *(unsigned long 
*)decode_register(sib & 7, regs, 0);
+                                opnd_off = *(unsigned long *)
+                                    decode_register(sib & 7, regs, 0);
                             opnd_off <<= sib >> 3;
                         }
                         if ( (modrm & 7) != 5 || (modrm & 0xc0) )
-                            opnd_off += *(unsigned long 
*)decode_register(modrm & 7, regs, 0);
+                            opnd_off += *(unsigned long *)
+                                decode_register(modrm & 7, regs, 0);
                         else
                             modrm |= 0x87;
                         if ( !opnd_sel )

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.