All of lore.kernel.org
 help / color / mirror / Atom feed
* Xen Security Advisory 7 (CVE-2012-0217) - PV privilege escalation
@ 2012-06-12 12:02 Xen.org security team
  2012-06-12 12:15 ` Andy Smith
  0 siblings, 1 reply; 3+ messages in thread
From: Xen.org security team @ 2012-06-12 12:02 UTC (permalink / raw)
  To: xen-announce-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR,
	xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR,
	xen-users-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR,
	oss-security-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8

[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 3771 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

              Xen Security Advisory CVE-2012-0217 / XSA-7
                            version 9

           64-bit PV guest privilege escalation vulnerability

UPDATES IN VERSION 9
====================

Public release.  Previous versions were embargoed.

ISSUE DESCRIPTION
=================

Rafal Wojtczuk has discovered a vulnerability which can allow a 64-bit
PV guest kernel running on a 64-bit hypervisor to escalate privileges
to that of the host by arranging for a system call to return via
sysret to a non-canonical RIP.  Intel CPUs deliver the resulting
exception in an undesirable processor state.

IMPACT
======

Guest administrators can gain control of the host.

Depending on the particular guest kernel it is also possible that
non-privileged guest user processes can also elevate their privileges
to that of the host.

VULNERABLE SYSTEMS
==================

All systems running 64 bit Xen hypervisor running 64 bit PV guests on
Intel CPUs are vulnerable to this issue.

Systems using AMD CPUs are not vulnerable to this privilege
escalation. AMD have issued the following statement:
   AMD processors' SYSRET behavior is such that a non-canonical
   address in RCX does not generate a #GP while in CPL0. We have
   verified this with our architecture team, with our design team, and
   have performed tests that verified this on silicon. Therefore, this
   privilege escalation exposure is not applicable to any AMD
   processor.

While investigating this, it was noted that some older AMD CPUs will
lock up under similar circumstances, causing a denial of service. See
XSA-9 for details.

MITIGATION
==========

This issue can be mitigated by running HVM (fully-virtualised)
or 32 bit PV guests only.

RESOLUTION
==========

Applying the appropriate attached patch will resolve the issue.

These patches also resolve the issue described in XSA-8 (CVE-2012-0128).

These changes have been made to the staging Xen repositories:
                    XSA-7:              XSA-8:
 xen-unstable.hg     25480:76eaf5966c05  25200:80f4113be500+25204:569d6f05e1ef
 xen-4.1-testing.hg  23299:f08e61b9b33f  23300:0fec1afa4638
 xen-4.0-testing.hg  21590:dd367837e089  21591:adb943a387c8
 xen-3.4-testing.hg  19996:894aa06e4f79  19997:ddb7578abb89

PATCH INFORMATION
=================

The attached patches resolve both this issue and that reported in
XSA-8 (CVE-2012-0128).

 xen-unstable 25204:569d6f05e1ef or later    xsa7-xsa8-unstable-recent.patch  
 xen-unstable 25199:6092641e3644 or earlier  xsa7-xsa8-unstable-apr16.patch
 Xen 4.1, 4.1.x                              xsa7-xsa8-xen-4.1.patch
 Xen 4.0, 4.0.x                              xsa7-xsa8-xen-4.0.patch
 Xen 3.4, 3.4.x                              xsa7-xsa8-xen-3.4.patch

$ sha256sum xsa7-xsa8-*patch
00853d799d24af16b17c8bbbdb5bb5144a8a7fad31467c4be3d879244774f8d2  xsa7-xsa8-unstable-apr16.patch
71f9907a58c1a1cd601d8088faf8791923d78f77065b94dba8df2a61f512530d  xsa7-xsa8-unstable-recent.patch
55fb925a7f4519ea31a0bc42d3ee83093bb7abd98b3a0e4f58591f1ae738840a  xsa7-xsa8-xen-3.4.patch
6a7e39121ec1f134351fdf34f494d108500aaa4190a9f7965e81c4e96270924e  xsa7-xsa8-xen-4.0.patch
52d8288718b4a833eb437fd18d92b7d412fbe01900dbd0b437744a1df4d459da  xsa7-xsa8-xen-4.1.patch
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQEcBAEBAgAGBQJP1yqTAAoJEIP+FMlX6CvZntwH/jzuqabF9yGMIXQBckjZUv1E
XeY9dbz1uGoMzy0mBFufwbJQqdBt89SNYDkr2BxKxSghSvBs608KHuh8giF1hzvm
8oP2K5T3Rk/jl0gdc3VlZz15Yi9kVEDUOSu2rPQLbhmiv6ht+Y2Of2cp63RioEvq
G2QQouHDsipCUZV4Ow5xnPY/KBifh46uCCnLDjV5Q/6WScI8VOIreOADryOpn2+/
8QmyCo2Sl2F+YxlbCl7k3qyqihaSONymeVg0pkJbH5LmRdTQnJX9fMJSQvfV6Bxs
U4PD4ve0C9+/Usz4XFejlQLt/kv4ZNPD6QF2rXei3oElmYAVcHL2XdLVCNLbAeY=
=S6KX
-----END PGP SIGNATURE-----


[-- Attachment #2: xsa7-xsa8-unstable-recent.patch --]
[-- Type: application/octet-stream, Size: 1589 bytes --]

x86_64: Do not execute sysret with a non-canonical return address

Check for non-canonical guest RIP before attempting to execute sysret.
If sysret is executed with a non-canonical value in RCX, Intel CPUs
take the fault in ring0, but we will necessarily already have switched
to the the user's stack pointer.

This is a security vulnerability, XSA-7 / CVE-2012-0217.

Signed-off-by: Jan Beulich <JBeulich@suse.com>
Signed-off-by: Ian Campbell <Ian.Campbell@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Tested-by: Ian Campbell <Ian.Campbell@citrix.com>
Acked-by: Keir Fraser <keir.xen@gmail.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>

diff -r 340062faf298 -r ad87903fdca1 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Wed May 23 11:06:49 2012 +0100
+++ b/xen/arch/x86/x86_64/entry.S	Thu May 24 11:02:35 2012 +0100
@@ -40,6 +40,13 @@ restore_all_guest:
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
 
+        /* Don't use SYSRET path if the return address is not canonical. */
+        movq  8(%rsp),%rcx
+        sarq  $47,%rcx
+        incl  %ecx
+        cmpl  $1,%ecx
+        ja    .Lforce_iret
+
         addq  $8,%rsp
         popq  %rcx                    # RIP
         popq  %r11                    # CS
@@ -50,6 +57,10 @@ restore_all_guest:
         sysretq
 1:      sysretl
 
+.Lforce_iret:
+        /* Mimic SYSRET behavior. */
+        movq  8(%rsp),%rcx            # RIP
+        movq  24(%rsp),%r11           # RFLAGS
         ALIGN
 /* No special register assumptions. */
 iret_exit_to_guest:

[-- Attachment #3: xsa7-xsa8-unstable-apr16.patch --]
[-- Type: application/octet-stream, Size: 5044 bytes --]

diff -r 6092641e3644 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c	Tue Apr 17 15:05:05 2012 +0200
+++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu May 24 11:05:19 2012 +0100
@@ -145,6 +145,7 @@ void __dummy__(void)
 
     OFFSET(TRAPINFO_eip, struct trap_info, address);
     OFFSET(TRAPINFO_cs, struct trap_info, cs);
+    OFFSET(TRAPINFO_flags, struct trap_info, flags);
     DEFINE(TRAPINFO_sizeof, sizeof(struct trap_info));
     BLANK();
 
diff -r 6092641e3644 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S	Tue Apr 17 15:05:05 2012 +0200
+++ b/xen/arch/x86/x86_64/compat/entry.S	Thu May 24 11:05:19 2012 +0100
@@ -213,6 +213,7 @@ 1:      call  compat_create_bounce_frame
 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
@@ -225,20 +226,21 @@ ENTRY(compat_syscall)
         leaq  VCPU_trap_bounce(%rbx),%rdx
         testl $~3,%esi
         leal  (,%rcx,TBF_INTERRUPT),%ecx
-        jz    2f
-1:      movq  %rax,TRAPBOUNCE_eip(%rdx)
+UNLIKELY_START(z, compat_syscall_gpf)
+        movq  VCPU_trap_ctxt(%rbx),%rdi
+        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+        subl  $2,UREGS_rip(%rsp)
+        movl  $0,TRAPBOUNCE_error_code(%rdx)
+        movl  TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rdi),%eax
+        movzwl TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_cs(%rdi),%esi
+        testb $4,TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_flags(%rdi)
+        setnz %cl
+        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
+UNLIKELY_END(compat_syscall_gpf)
+        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
-2:      movq  VCPU_trap_ctxt(%rbx),%rsi
-        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
-        subl  $2,UREGS_rip(%rsp)
-        movl  TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%eax
-        movzwl TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_cs(%rsi),%esi
-        movb  $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
-        movl  $0,TRAPBOUNCE_error_code(%rdx)
-        jmp   1b
+        jmp   .Lcompat_bounce_exception
 
 ENTRY(compat_sysenter)
         movq  VCPU_trap_ctxt(%rbx),%rcx
diff -r 6092641e3644 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Tue Apr 17 15:05:05 2012 +0200
+++ b/xen/arch/x86/x86_64/entry.S	Thu May 24 11:05:19 2012 +0100
@@ -40,6 +40,13 @@ restore_all_guest:
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
 
+        /* Don't use SYSRET path if the return address is not canonical. */
+        movq  8(%rsp),%rcx
+        sarq  $47,%rcx
+        incl  %ecx
+        cmpl  $1,%ecx
+        ja    .Lforce_iret
+
         addq  $8,%rsp
         popq  %rcx                    # RIP
         popq  %r11                    # CS
@@ -50,6 +57,10 @@ restore_all_guest:
         sysretq
 1:      sysretl
 
+.Lforce_iret:
+        /* Mimic SYSRET behavior. */
+        movq  8(%rsp),%rcx            # RIP
+        movq  24(%rsp),%r11           # RFLAGS
         ALIGN
 /* No special register assumptions. */
 iret_exit_to_guest:
@@ -277,20 +288,22 @@ sysenter_eflags_saved:
         leaq  VCPU_trap_bounce(%rbx),%rdx
         testq %rax,%rax
         leal  (,%rcx,TBF_INTERRUPT),%ecx
-        jz    2f
-1:      movq  VCPU_domain(%rbx),%rdi
+UNLIKELY_START(z, sysenter_gpf)
+        movq  VCPU_trap_ctxt(%rbx),%rsi
+        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+        subq  $2,UREGS_rip(%rsp)
+        movl  %eax,TRAPBOUNCE_error_code(%rdx)
+        movq  TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%rax
+        testb $4,TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_flags(%rsi)
+        setnz %cl
+        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
+UNLIKELY_END(sysenter_gpf)
+        movq  VCPU_domain(%rbx),%rdi
         movq  %rax,TRAPBOUNCE_eip(%rdx)
         movb  %cl,TRAPBOUNCE_flags(%rdx)
         testb $1,DOMAIN_is_32bit_pv(%rdi)
         jnz   compat_sysenter
-        call  create_bounce_frame
-        jmp   test_all_events
-2:      movq  VCPU_trap_ctxt(%rbx),%rcx
-        movl  %eax,TRAPBOUNCE_error_code(%rdx)
-        movq  TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rcx),%rax
-        movb  $(TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE|TBF_INTERRUPT),%cl
-        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
-        jmp   1b
+        jmp   .Lbounce_exception
 
 ENTRY(int80_direct_trap)
         pushq $0
@@ -483,6 +496,7 @@ 1:      movq  %rsp,%rdi
         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

[-- Attachment #4: xsa7-xsa8-xen-4.1.patch --]
[-- Type: application/octet-stream, Size: 4939 bytes --]

diff -r 35248be669e7 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c	Mon May 14 16:59:12 2012 +0100
+++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu May 24 11:12:33 2012 +0100
@@ -90,6 +90,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 -r 35248be669e7 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S	Mon May 14 16:59:12 2012 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S	Thu May 24 11:12:33 2012 +0100
@@ -214,6 +214,7 @@ 1:      call  compat_create_bounce_frame
 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
@@ -226,19 +227,20 @@ ENTRY(compat_syscall)
         leaq  VCPU_trap_bounce(%rbx),%rdx
         testl $~3,%esi
         leal  (,%rcx,TBF_INTERRUPT),%ecx
-        jz    2f
-1:      movq  %rax,TRAPBOUNCE_eip(%rdx)
+UNLIKELY_START(z, compat_syscall_gpf)
+        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+        subl  $2,UREGS_rip(%rsp)
+        movl  $0,TRAPBOUNCE_error_code(%rdx)
+        movl  VCPU_gp_fault_addr(%rbx),%eax
+        movzwl VCPU_gp_fault_sel(%rbx),%esi
+        testb $4,VCPU_gp_fault_flags(%rbx)
+        setnz %cl
+        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
+UNLIKELY_END(compat_syscall_gpf)
+        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
-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)
-        jmp   1b
+        jmp   .Lcompat_bounce_exception
 
 ENTRY(compat_sysenter)
         cmpl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
diff -r 35248be669e7 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Mon May 14 16:59:12 2012 +0100
+++ b/xen/arch/x86/x86_64/entry.S	Thu May 24 11:12:33 2012 +0100
@@ -40,6 +40,13 @@ restore_all_guest:
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
 
+        /* Don't use SYSRET path if the return address is not canonical. */
+        movq  8(%rsp),%rcx
+        sarq  $47,%rcx
+        incl  %ecx
+        cmpl  $1,%ecx
+        ja    .Lforce_iret
+
         addq  $8,%rsp
         popq  %rcx                    # RIP
         popq  %r11                    # CS
@@ -50,6 +57,10 @@ restore_all_guest:
         sysretq
 1:      sysretl
 
+.Lforce_iret:
+        /* Mimic SYSRET behavior. */
+        movq  8(%rsp),%rcx            # RIP
+        movq  24(%rsp),%r11           # RFLAGS
         ALIGN
 /* No special register assumptions. */
 iret_exit_to_guest:
@@ -278,19 +289,21 @@ sysenter_eflags_saved:
         leaq  VCPU_trap_bounce(%rbx),%rdx
         testq %rax,%rax
         leal  (,%rcx,TBF_INTERRUPT),%ecx
-        jz    2f
-1:      movq  VCPU_domain(%rbx),%rdi
+UNLIKELY_START(z, sysenter_gpf)
+        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+        subq  $2,UREGS_rip(%rsp)
+        movl  %eax,TRAPBOUNCE_error_code(%rdx)
+        movq  VCPU_gp_fault_addr(%rbx),%rax
+        testb $4,VCPU_gp_fault_flags(%rbx)
+        setnz %cl
+        leal  TBF_EXCEPTION|TBF_EXCEPTION_ERRCODE(,%rcx,TBF_INTERRUPT),%ecx
+UNLIKELY_END(sysenter_gpf)
+        movq  VCPU_domain(%rbx),%rdi
         movq  %rax,TRAPBOUNCE_eip(%rdx)
         movb  %cl,TRAPBOUNCE_flags(%rdx)
         testb $1,DOMAIN_is_32bit_pv(%rdi)
         jnz   compat_sysenter
-        call  create_bounce_frame
-        jmp   test_all_events
-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)
-        jmp   1b
+        jmp   .Lbounce_exception
 
 ENTRY(int80_direct_trap)
         pushq $0
@@ -482,6 +495,7 @@ 1:      movq  %rsp,%rdi
         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

[-- Attachment #5: xsa7-xsa8-xen-4.0.patch --]
[-- Type: application/octet-stream, Size: 3960 bytes --]

diff -r d8fd425b60d3 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c	Tue May 01 14:18:46 2012 +0100
+++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu May 24 11:18:47 2012 +0100
@@ -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 -r d8fd425b60d3 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S	Tue May 01 14:18:46 2012 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S	Thu May 24 11:18:47 2012 +0100
@@ -227,6 +227,7 @@ 1:      call  compat_create_bounce_frame
 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 -r d8fd425b60d3 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Tue May 01 14:18:46 2012 +0100
+++ b/xen/arch/x86/x86_64/entry.S	Thu May 24 11:18:47 2012 +0100
@@ -51,6 +51,13 @@ restore_all_guest:
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
 
+        /* Don't use SYSRET path if the return address is not canonical. */
+        movq  8(%rsp),%rcx
+        sarq  $47,%rcx
+        incl  %ecx
+        cmpl  $1,%ecx
+        ja    .Lforce_iret
+
         addq  $8,%rsp
         popq  %rcx                    # RIP
         popq  %r11                    # CS
@@ -61,6 +68,10 @@ restore_all_guest:
         sysretq
 1:      sysretl
 
+.Lforce_iret:
+        /* Mimic SYSRET behavior. */
+        movq  8(%rsp),%rcx            # RIP
+        movq  24(%rsp),%r11           # RFLAGS
         ALIGN
 /* No special register assumptions. */
 iret_exit_to_guest:
@@ -298,12 +309,14 @@ 1:      movq  VCPU_domain(%rbx),%rdi
         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)
@@ -490,6 +503,7 @@ 1:      movq  %rsp,%rdi
         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

[-- Attachment #6: xsa7-xsa8-xen-3.4.patch --]
[-- Type: application/octet-stream, Size: 3960 bytes --]

diff -r 51bd1f172758 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c	Fri Sep 30 17:35:29 2011 -0400
+++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu May 24 12:41:08 2012 +0100
@@ -90,6 +90,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 -r 51bd1f172758 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S	Fri Sep 30 17:35:29 2011 -0400
+++ b/xen/arch/x86/x86_64/compat/entry.S	Thu May 24 12:41:08 2012 +0100
@@ -215,6 +215,7 @@ 1:      call  compat_create_bounce_frame
 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
@@ -231,14 +232,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 -r 51bd1f172758 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Fri Sep 30 17:35:29 2011 -0400
+++ b/xen/arch/x86/x86_64/entry.S	Thu May 24 12:41:08 2012 +0100
@@ -51,6 +51,13 @@ restore_all_guest:
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
 
+        /* Don't use SYSRET path if the return address is not canonical. */
+        movq  8(%rsp),%rcx
+        sarq  $47,%rcx
+        incl  %ecx
+        cmpl  $1,%ecx
+        ja    .Lforce_iret
+
         addq  $8,%rsp
         popq  %rcx                    # RIP
         popq  %r11                    # CS
@@ -61,6 +68,10 @@ restore_all_guest:
         sysretq
 1:      sysretl
 
+.Lforce_iret:
+        /* Mimic SYSRET behavior. */
+        movq  8(%rsp),%rcx            # RIP
+        movq  24(%rsp),%r11           # RFLAGS
         ALIGN
 /* No special register assumptions. */
 iret_exit_to_guest:
@@ -296,12 +307,14 @@ 1:      movq  VCPU_domain(%rbx),%rdi
         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)
@@ -480,6 +493,7 @@ 1:      movq  %rsp,%rdi
         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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-06-12 14:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-12 12:02 Xen Security Advisory 7 (CVE-2012-0217) - PV privilege escalation Xen.org security team
2012-06-12 12:15 ` Andy Smith
2012-06-12 14:06   ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.