aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_64
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-04-18 16:00:35 +0200
committerJan Beulich <jbeulich@suse.com>2013-04-18 16:00:35 +0200
commitfdac9515607b757c044e7ef0d61b1453ef999b08 (patch)
treeb853bb0f046d2e6e62222476e607ebb0153f6715 /xen/arch/x86/x86_64
parent8d266f6b2c5c3d2d0da42f1e40ba1fb2ac8fdf1a (diff)
downloadxen-fdac9515607b757c044e7ef0d61b1453ef999b08.tar.gz
xen-fdac9515607b757c044e7ef0d61b1453ef999b08.tar.bz2
xen-fdac9515607b757c044e7ef0d61b1453ef999b08.zip
x86: clear EFLAGS.NT in SYSENTER entry path
... as it causes problems if we happen to exit back via IRET: In the course of trying to handle the fault, the hypervisor creates a stack frame by hand, and uses PUSHFQ to set the respective EFLAGS field, but expects to be able to IRET through that stack frame to the second portion of the fixup code (which causes a #GP due to the stored EFLAGS having NT set). And even if this worked (e.g if we cleared NT in that path), it would then (through the fail safe callback) cause a #GP in the guest with the SYSENTER handler's first instruction as the source, which in turn would allow guest user mode code to crash the guest kernel. Inject a #GP on the fake (NULL) address of the SYSENTER instruction instead, just like in the case where the guest kernel didn't register a corresponding entry point. This is CVE-2013-1917 / XSA-44. Reported-by: Andrew Cooper <andrew.cooper3@citirx.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Tested-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Diffstat (limited to 'xen/arch/x86/x86_64')
-rw-r--r--xen/arch/x86/x86_64/entry.S7
1 files changed, 7 insertions, 0 deletions
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 03e352bda3..5beeccb647 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -282,7 +282,14 @@ sysenter_eflags_saved:
cmpb $0,VCPU_sysenter_disables_events(%rbx)
movq VCPU_sysenter_addr(%rbx),%rax
setne %cl
+ testl $X86_EFLAGS_NT,UREGS_eflags(%rsp)
leaq VCPU_trap_bounce(%rbx),%rdx
+UNLIKELY_START(nz, sysenter_nt_set)
+ pushfq
+ andl $~X86_EFLAGS_NT,(%rsp)
+ popfq
+ xorl %eax,%eax
+UNLIKELY_END(sysenter_nt_set)
testq %rax,%rax
leal (,%rcx,TBF_INTERRUPT),%ecx
UNLIKELY_START(z, sysenter_gpf)