aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-06-04 09:40:12 +0200
committerJan Beulich <jbeulich@suse.com>2013-06-04 09:40:12 +0200
commit5849504a03725f553195c8d80b0d595ef8334e2a (patch)
tree7c59078ca5f211b069e423290340a42724fb5730
parentc3401c1aece47dc5388184c9b6a3527655d5bbdf (diff)
downloadxen-5849504a03725f553195c8d80b0d595ef8334e2a.tar.gz
xen-5849504a03725f553195c8d80b0d595ef8334e2a.tar.bz2
xen-5849504a03725f553195c8d80b0d595ef8334e2a.zip
x86/xsave: recover from faults on XRSTOR
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
-rw-r--r--xen/arch/x86/i387.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
index 6e22eba752..bba14ca978 100644
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -59,10 +59,25 @@ static void xrstor(struct vcpu *v)
"fildl %0" /* load to clear state */
: : "m" (ptr->fpu_sse) );
- asm volatile (
- ".byte " REX_PREFIX "0x0f,0xae,0x2f"
- :
- : "m" (*ptr), "a" (-1), "d" (-1), "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 %4,%%ecx \n"
+ " xor %1,%1 \n"
+ " rep stosb \n"
+ " lea %3,%0 \n"
+ " dec %1 \n"
+ " jmp 1b \n"
+ ".previous \n"
+ _ASM_EXTABLE(1b, 2b)
+ : "+&D" (ptr)
+ : "a" (-1), "d" (-1), "m" (*ptr),
+ "m" (xsave_cntxt_size)
+ : "ecx" );
}
static void load_mxcsr(unsigned long val)
@@ -196,7 +211,7 @@ static void restore_fpu(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.
*/
if ( cpu_has_fxsr )
{