xcp-1.6-updates/xen-4.1.hg

changeset 23300:0fec1afa4638

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>
author Jan Beulich <JBeulich@suse.com>
date Tue Jun 12 11:46:11 2012 +0100 (2012-06-12)
parents f08e61b9b33f
children a9c0a89c08f2
files xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/compat/entry.S xen/arch/x86/x86_64/entry.S
line diff
     1.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Tue Jun 12 11:38:30 2012 +0100
     1.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Tue Jun 12 11:46:11 2012 +0100
     1.3 @@ -90,6 +90,8 @@ void __dummy__(void)
     1.4             arch.guest_context.trap_ctxt[TRAP_gp_fault].address);
     1.5      OFFSET(VCPU_gp_fault_sel, struct vcpu,
     1.6             arch.guest_context.trap_ctxt[TRAP_gp_fault].cs);
     1.7 +    OFFSET(VCPU_gp_fault_flags, struct vcpu,
     1.8 +           arch.guest_context.trap_ctxt[TRAP_gp_fault].flags);
     1.9      OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp);
    1.10      OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss);
    1.11      OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
     2.1 --- a/xen/arch/x86/x86_64/compat/entry.S	Tue Jun 12 11:38:30 2012 +0100
     2.2 +++ b/xen/arch/x86/x86_64/compat/entry.S	Tue Jun 12 11:46:11 2012 +0100
     2.3 @@ -214,6 +214,7 @@ 1:      call  compat_create_bounce_frame
     2.4  ENTRY(compat_post_handle_exception)
     2.5          testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
     2.6          jz    compat_test_all_events
     2.7 +.Lcompat_bounce_exception:
     2.8          call  compat_create_bounce_frame
     2.9          movb  $0,TRAPBOUNCE_flags(%rdx)
    2.10          jmp   compat_test_all_events
    2.11 @@ -226,19 +227,20 @@ ENTRY(compat_syscall)
    2.12          leaq  VCPU_trap_bounce(%rbx),%rdx
    2.13          testl $~3,%esi
    2.14          leal  (,%rcx,TBF_INTERRUPT),%ecx
    2.15 -        jz    2f
    2.16 -1:      movq  %rax,TRAPBOUNCE_eip(%rdx)
    2.17 +UNLIKELY_START(z, compat_syscall_gpf)
    2.18 +        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
    2.19 +        subl  $2,UREGS_rip(%rsp)
    2.20 +        movl  $0,TRAPBOUNCE_error_code(%rdx)
    2.21 +        movl  VCPU_gp_fault_addr(%rbx),%eax
    2.22 +        movzwl VCPU_gp_fault_sel(%rbx),%esi
    2.23 +        testb $4,VCPU_gp_fault_flags(%rbx)
    2.24 +        setnz %cl
    2.25 +        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
    2.26 +UNLIKELY_END(compat_syscall_gpf)
    2.27 +        movq  %rax,TRAPBOUNCE_eip(%rdx)
    2.28          movw  %si,TRAPBOUNCE_cs(%rdx)
    2.29          movb  %cl,TRAPBOUNCE_flags(%rdx)
    2.30 -        call  compat_create_bounce_frame
    2.31 -        jmp   compat_test_all_events
    2.32 -2:      movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
    2.33 -        subl  $2,UREGS_rip(%rsp)
    2.34 -        movq  VCPU_gp_fault_addr(%rbx),%rax
    2.35 -        movzwl VCPU_gp_fault_sel(%rbx),%esi
    2.36 -        movb  $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
    2.37 -        movl  $0,TRAPBOUNCE_error_code(%rdx)
    2.38 -        jmp   1b
    2.39 +        jmp   .Lcompat_bounce_exception
    2.40  
    2.41  ENTRY(compat_sysenter)
    2.42          cmpl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
     3.1 --- a/xen/arch/x86/x86_64/entry.S	Tue Jun 12 11:38:30 2012 +0100
     3.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Jun 12 11:46:11 2012 +0100
     3.3 @@ -289,19 +289,21 @@ sysenter_eflags_saved:
     3.4          leaq  VCPU_trap_bounce(%rbx),%rdx
     3.5          testq %rax,%rax
     3.6          leal  (,%rcx,TBF_INTERRUPT),%ecx
     3.7 -        jz    2f
     3.8 -1:      movq  VCPU_domain(%rbx),%rdi
     3.9 +UNLIKELY_START(z, sysenter_gpf)
    3.10 +        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
    3.11 +        subq  $2,UREGS_rip(%rsp)
    3.12 +        movl  %eax,TRAPBOUNCE_error_code(%rdx)
    3.13 +        movq  VCPU_gp_fault_addr(%rbx),%rax
    3.14 +        testb $4,VCPU_gp_fault_flags(%rbx)
    3.15 +        setnz %cl
    3.16 +        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
    3.17 +UNLIKELY_END(sysenter_gpf)
    3.18 +        movq  VCPU_domain(%rbx),%rdi
    3.19          movq  %rax,TRAPBOUNCE_eip(%rdx)
    3.20          movb  %cl,TRAPBOUNCE_flags(%rdx)
    3.21          testb $1,DOMAIN_is_32bit_pv(%rdi)
    3.22          jnz   compat_sysenter
    3.23 -        call  create_bounce_frame
    3.24 -        jmp   test_all_events
    3.25 -2:      movl  %eax,TRAPBOUNCE_error_code(%rdx)
    3.26 -        movq  VCPU_gp_fault_addr(%rbx),%rax
    3.27 -        movb  $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
    3.28 -        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
    3.29 -        jmp   1b
    3.30 +        jmp   .Lbounce_exception
    3.31  
    3.32  ENTRY(int80_direct_trap)
    3.33          pushq $0
    3.34 @@ -493,6 +495,7 @@ 1:      movq  %rsp,%rdi
    3.35          jnz   compat_post_handle_exception
    3.36          testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
    3.37          jz    test_all_events
    3.38 +.Lbounce_exception:
    3.39          call  create_bounce_frame
    3.40          movb  $0,TRAPBOUNCE_flags(%rdx)
    3.41          jmp   test_all_events