]> xenbits.xensource.com Git - xen.git/commitdiff
x86/xsave: recover from faults on XRSTOR
authorJan Beulich <jbeulich@suse.com>
Tue, 4 Jun 2013 07:35:16 +0000 (09:35 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 4 Jun 2013 07:35:16 +0000 (09:35 +0200)
Just like FXRSTOR, XRSTOR can raise #GP if bad content is being passed
to it in the memory block (i.e. aspects not under the control of the
hypervisor, other than e.g. proper alignment of the block).

Also correct the comment explaining why FXRSTOR needs exception
recovery code to not wrongly state that this can only be a result of
the control tools passing a bad image.

This is CVE-2013-2077 / XSA-53.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
master commit: c6ae65db36b98f2866f74a9a7ae6ac5d51fedc67
master date: 2013-06-04 09:27:58 +0200

xen/arch/x86/i387.c
xen/arch/x86/xstate.c

index 0ec2308e455a39cccb1b64f977efc5db234ab2fc..e5f889560a4bc1220ed1bcf8fa91720685e51eb4 100644 (file)
@@ -53,7 +53,7 @@ static inline void fpu_fxrstor(struct vcpu *v)
     /*
      * FXRSTOR can fault if passed a corrupted data block. We handle this
      * possibility, which may occur if the block was passed to us by control
-     * tools, by silently clearing the block.
+     * tools or through VCPUOP_initialise, by silently clearing the block.
      */
     asm volatile (
 #ifdef __i386__
index ee879e43fa05e240244cd71a0688fd535592d9c7..014523322cb7b087b0dcc903e0a215dda21d0067 100644 (file)
@@ -93,10 +93,25 @@ void xrstor(struct vcpu *v, uint64_t mask)
                        "fildl %0"          /* load to clear state */
                        : : "m" (ptr->fpu_sse) );
 
-    asm volatile (
-        ".byte " REX_PREFIX "0x0f,0xae,0x2f"
-        :
-        : "m" (*ptr), "a" (lmask), "d" (hmask), "D"(ptr) );
+    /*
+     * XRSTOR can fault if passed a corrupted data block. We handle this
+     * possibility, which may occur if the block was passed to us by control
+     * tools or through VCPUOP_initialise, by silently clearing the block.
+     */
+    asm volatile ( "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
+                   ".section .fixup,\"ax\"\n"
+                   "2: mov %5,%%ecx       \n"
+                   "   xor %1,%1          \n"
+                   "   rep stosb          \n"
+                   "   lea %2,%0          \n"
+                   "   mov %3,%1          \n"
+                   "   jmp 1b             \n"
+                   ".previous             \n"
+                   _ASM_EXTABLE(1b, 2b)
+                   : "+&D" (ptr), "+&a" (lmask)
+                   : "m" (*ptr), "g" (lmask), "d" (hmask),
+                     "m" (xsave_cntxt_size)
+                   : "ecx" );
 }
 
 bool_t xsave_enabled(const struct vcpu *v)