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 <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
master commit:
63a75ba0de817d6f384f96d25427a05c313e2179
master date: 2013-09-25 10:41:25 +0200
int handle_xsetbv(u32 index, u64 new_bv)
{
struct vcpu *curr = current;
+ u64 mask;
if ( index != XCR_XFEATURE_ENABLED_MASK )
return -EOPNOTSUPP;
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;
}