x86: fix information leak on AMD CPUs
authorJan Beulich <jbeulich@suse.com>
Tue, 29 Mar 2016 12:24:26 +0000 (14:24 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 29 Mar 2016 12:24:26 +0000 (14:24 +0200)
The fix for XSA-52 was wrong, and so was the change synchronizing that
new behavior to the FXRSTOR logic: AMD's manuals explictly state that
writes to the ES bit are ignored, and it instead gets calculated from
the exception and mask bits (it gets set whenever there is an unmasked
exception, and cleared otherwise). Hence we need to follow that model
in our workaround.

This is CVE-2016-3158 / CVE-2016-3159 / XSA-172.
[xen/arch/x86/xstate.c:xrstor: CVE-2016-3158]
[xen/arch/x86/i387.c:fpu_fxrstor: CVE-2016-3159]

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/i387.c
xen/arch/x86/xstate.c

index c29d0fa7b5ea40f6557dd0a34d3a91fe7899997e..1a3e2771bd5970f319f415c2bb5aa0e81322988a 100644 (file)
@@ -49,7 +49,7 @@ static inline void fpu_fxrstor(struct vcpu *v)
      * sometimes new user value. Both should be ok. Use the FPU saved
      * data block as a safe address because it should be in L1.
      */
-    if ( !(fpu_ctxt->fsw & 0x0080) &&
+    if ( !(fpu_ctxt->fsw & ~fpu_ctxt->fcw & 0x003f) &&
          boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
     {
         asm volatile ( "fnclex\n\t"
index f64940538ef62bf783a650d71cc553b276f9aa17..78cbfbb74511d93c64728bcbcf49f0ab27c3783e 100644 (file)
@@ -333,7 +333,7 @@ void xrstor(struct vcpu *v, uint64_t mask)
      * data block as a safe address because it should be in L1.
      */
     if ( (mask & ptr->xsave_hdr.xstate_bv & XSTATE_FP) &&
-         !(ptr->fpu_sse.fsw & 0x0080) &&
+         !(ptr->fpu_sse.fsw & ~ptr->fpu_sse.fcw & 0x003f) &&
          boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
         asm volatile ( "fnclex\n\t"        /* clear exceptions */
                        "ffree %%st(7)\n\t" /* clear stack tag */