diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-06-04 09:27:58 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-06-04 09:27:58 +0200 |
commit | c6ae65db36b98f2866f74a9a7ae6ac5d51fedc67 (patch) | |
tree | 301dac31411d313e98bda1e9b58d6ed431dded34 /xen/arch/x86/xstate.c | |
parent | 8dcf9f0113454f233089e8e5bb3970d891928410 (diff) | |
download | xen-c6ae65db36b98f2866f74a9a7ae6ac5d51fedc67.tar.gz xen-c6ae65db36b98f2866f74a9a7ae6ac5d51fedc67.tar.bz2 xen-c6ae65db36b98f2866f74a9a7ae6ac5d51fedc67.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>
Diffstat (limited to 'xen/arch/x86/xstate.c')
-rw-r--r-- | xen/arch/x86/xstate.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index 9fe5eecd5d..a0d036d6c2 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -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) |