aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2012-06-12 11:39:34 +0100
committerJan Beulich <JBeulich@suse.com>2012-06-12 11:39:34 +0100
commitc7c2c622562502c6c7e9bfe38c342d4f25746f1f (patch)
tree6525b13012ae7380a06c101e777c604db59ec273
parent00330de0073ca61fa45bd800df2cc4f4a947cbc9 (diff)
downloadxen-c7c2c622562502c6c7e9bfe38c342d4f25746f1f.tar.gz
xen-c7c2c622562502c6c7e9bfe38c342d4f25746f1f.tar.bz2
xen-c7c2c622562502c6c7e9bfe38c342d4f25746f1f.zip
x86-64: fix #GP generation in assembly code
When guest use of sysenter (64-bit PV guest) or syscall (32-bit PV guest) gets converted into a GP fault (due to no callback having got registered), we must - honor the GP fault handler's request the keep enabled or mask event delivery - not allow TBF_EXCEPTION to remain set past the generation of the (guest) exception in the vCPU's trap_bounce.flags, as that would otherwise allow for the next exception occurring in guest mode, should it happen to get handled in Xen itself, to nevertheless get bounced to the guest kernel. Also, just like compat mode syscall handling already did, native mode sysenter handling should, when converting to #GP, subtract 2 from the RIP present in the frame so that the guest's GP fault handler would see the fault pointing to the offending instruction instead of past it. Finally, since those exception generating code blocks needed to be modified anyway, convert them to make use of UNLIKELY_{START,END}(). [ This bug is security vulnerability, XSA-8 / CVE-2012-0218. ] Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org> Committed-by: Jan Beulich <jbeulich@suse.com> xen-unstable changeset: 25200:80f4113be500 25204:569d6f05e1ef Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
-rw-r--r--xen/arch/x86/x86_64/asm-offsets.c2
-rw-r--r--xen/arch/x86/x86_64/compat/entry.S8
-rw-r--r--xen/arch/x86/x86_64/entry.S9
3 files changed, 13 insertions, 6 deletions
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index c763ed0684..65583728a1 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -89,6 +89,8 @@ void __dummy__(void)
arch.guest_context.trap_ctxt[TRAP_gp_fault].address);
OFFSET(VCPU_gp_fault_sel, struct vcpu,
arch.guest_context.trap_ctxt[TRAP_gp_fault].cs);
+ OFFSET(VCPU_gp_fault_flags, struct vcpu,
+ arch.guest_context.trap_ctxt[TRAP_gp_fault].flags);
OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp);
OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss);
OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index 094a74ddb3..809c23f1f2 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -227,6 +227,7 @@ compat_failsafe_callback:
ENTRY(compat_post_handle_exception)
testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
jz compat_test_all_events
+.Lcompat_bounce_exception:
call compat_create_bounce_frame
movb $0,TRAPBOUNCE_flags(%rdx)
jmp compat_test_all_events
@@ -243,14 +244,15 @@ ENTRY(compat_syscall)
1: movq %rax,TRAPBOUNCE_eip(%rdx)
movw %si,TRAPBOUNCE_cs(%rdx)
movb %cl,TRAPBOUNCE_flags(%rdx)
- call compat_create_bounce_frame
- jmp compat_test_all_events
+ jmp .Lcompat_bounce_exception
2: movl $TRAP_gp_fault,UREGS_entry_vector(%rsp)
subl $2,UREGS_rip(%rsp)
movq VCPU_gp_fault_addr(%rbx),%rax
movzwl VCPU_gp_fault_sel(%rbx),%esi
- movb $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
movl $0,TRAPBOUNCE_error_code(%rdx)
+ testb $4,VCPU_gp_fault_flags(%rbx)
+ setnz %cl
+ leal TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
jmp 1b
ENTRY(compat_sysenter)
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index f42630f2dc..9e9db33106 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -309,12 +309,14 @@ sysenter_eflags_saved:
movb %cl,TRAPBOUNCE_flags(%rdx)
testb $1,DOMAIN_is_32bit_pv(%rdi)
jnz compat_sysenter
- call create_bounce_frame
- jmp test_all_events
+ jmp .Lbounce_exception
2: movl %eax,TRAPBOUNCE_error_code(%rdx)
movq VCPU_gp_fault_addr(%rbx),%rax
- movb $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
movl $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+ subq $2,UREGS_rip(%rsp)
+ testb $4,VCPU_gp_fault_flags(%rbx)
+ setnz %cl
+ leal TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
jmp 1b
ENTRY(int80_direct_trap)
@@ -501,6 +503,7 @@ handle_exception_saved:
jnz compat_post_handle_exception
testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
jz test_all_events
+.Lbounce_exception:
call create_bounce_frame
movb $0,TRAPBOUNCE_flags(%rdx)
jmp test_all_events