[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.1] x86: clear EFLAGS.NT in SYSENTER entry path
commit 584eb7c15e4c94baaba93468776572dd7373a33c Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Thu Apr 18 16:23:07 2013 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Apr 18 16:23:07 2013 +0200 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. On 32-bit we also need to make sure we clear SYSENTER_CS for all CPUs (neither #RESET nor #INIT guarantee this). This is CVE-2013-1917 / XSA-44. Reported-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Tested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> master commit: fdac9515607b757c044e7ef0d61b1453ef999b08 master date: 2013-04-18 16:00:35 +0200 --- xen/arch/x86/acpi/suspend.c | 8 ++++++-- xen/arch/x86/cpu/common.c | 5 ++++- xen/arch/x86/x86_64/entry.S | 7 +++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/acpi/suspend.c b/xen/arch/x86/acpi/suspend.c index 6f2ff5b..1c3aff4 100644 --- a/xen/arch/x86/acpi/suspend.c +++ b/xen/arch/x86/acpi/suspend.c @@ -81,8 +81,12 @@ void restore_rest_processor_state(void) } #else /* !defined(CONFIG_X86_64) */ - if ( supervisor_mode_kernel && cpu_has_sep ) - wrmsr(MSR_IA32_SYSENTER_ESP, &this_cpu(init_tss).esp1, 0); + if ( cpu_has_sep ) + { + wrmsr(MSR_IA32_SYSENTER_CS, 0, 0); + if ( supervisor_mode_kernel ) + wrmsr(MSR_IA32_SYSENTER_ESP, &this_cpu(init_tss).esp1, 0); + } #endif /* Maybe load the debug registers. */ diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index c3ddab6..a3a6b96 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -715,8 +715,11 @@ void __cpuinit cpu_init(void) #if defined(CONFIG_X86_32) t->ss0 = __HYPERVISOR_DS; t->esp0 = get_stack_bottom(); - if ( supervisor_mode_kernel && cpu_has_sep ) + if ( cpu_has_sep ) { + wrmsr(MSR_IA32_SYSENTER_CS, 0, 0); + if ( supervisor_mode_kernel ) wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0); + } #elif defined(CONFIG_X86_64) /* Bottom-of-stack must be 16-byte aligned! */ BUG_ON((get_stack_bottom() & 15) != 0); diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 2b8c99a..7b392d8 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -288,7 +288,14 @@ sysenter_eflags_saved: movl $3,UREGS_cs(%rsp) /* ring 3 null cs */ 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) -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.1 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |