From 12b0ee04a16194f064d5b895a844fcdc6414bfc0 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 25 Sep 2013 10:55:42 +0200 Subject: x86/xsave: initialize extended register state when guests enable it Till now, when setting previously unset bits in XCR0 we wouldn't touch the active register state, thus leaving in the newly enabled registers whatever a prior user of it left there, i.e. potentially leaking information between guests. This is CVE-2013-1442 / XSA-62. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper master commit: 63a75ba0de817d6f384f96d25427a05c313e2179 master date: 2013-09-25 10:41:25 +0200 --- xen/arch/x86/xstate.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index b0ac1ffdc7..37c52256ef 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -348,6 +348,7 @@ int validate_xstate(u64 xcr0, u64 xcr0_accum, u64 xstate_bv, u64 xfeat_mask) int handle_xsetbv(u32 index, u64 new_bv) { struct vcpu *curr = current; + u64 mask; if ( index != XCR_XFEATURE_ENABLED_MASK ) return -EOPNOTSUPP; @@ -361,9 +362,23 @@ int handle_xsetbv(u32 index, u64 new_bv) if ( !set_xcr0(new_bv) ) return -EFAULT; + mask = new_bv & ~curr->arch.xcr0_accum; curr->arch.xcr0 = new_bv; curr->arch.xcr0_accum |= new_bv; + mask &= curr->fpu_dirtied ? ~XSTATE_FP_SSE : XSTATE_NONLAZY; + if ( mask ) + { + unsigned long cr0 = read_cr0(); + + clts(); + if ( curr->fpu_dirtied ) + asm ( "stmxcsr %0" : "=m" (curr->arch.xsave_area->fpu_sse.mxcsr) ); + xrstor(curr, mask); + if ( cr0 & X86_CR0_TS ) + write_cr0(cr0); + } + return 0; } -- cgit v1.2.3