* 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* Re: Xen Security Advisory 7 (CVE-2012-0217) - PV privilege escalation
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
0 siblings, 1 reply; 3+ messages in thread
From: Andy Smith @ 2012-06-12 12:15 UTC (permalink / raw)
To: xen-devel
Hello,
A quick question with regard to XSA-7:
On Tue, Jun 12, 2012 at 01:02:32PM +0100, Xen.org security team wrote:
> MITIGATION
> ==========
>
> This issue can be mitigated by running HVM (fully-virtualised)
> or 32 bit PV guests only.
Assuming 64-bit hypervisor and dom0, with PV guests booted using
pygrub, is there any way to restrict guests to 32-bit only?
Cheers,
Andy
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Xen Security Advisory 7 (CVE-2012-0217) - PV privilege escalation
2012-06-12 12:15 ` Andy Smith
@ 2012-06-12 14:06 ` Ian Campbell
0 siblings, 0 replies; 3+ messages in thread
From: Ian Campbell @ 2012-06-12 14:06 UTC (permalink / raw)
To: Andy Smith; +Cc: xen-devel@lists.xen.org
On Tue, 2012-06-12 at 13:15 +0100, Andy Smith wrote:
> Hello,
>
> A quick question with regard to XSA-7:
>
> On Tue, Jun 12, 2012 at 01:02:32PM +0100, Xen.org security team wrote:
> > MITIGATION
> > ==========
> >
> > This issue can be mitigated by running HVM (fully-virtualised)
> > or 32 bit PV guests only.
>
> Assuming 64-bit hypervisor and dom0, with PV guests booted using
> pygrub, is there any way to restrict guests to 32-bit only?
Nothing which has been implemented but a couple of ideas which spring to
my mind, in no particular order:
* A wrapper around pygrub to vet the kernel which it has
extracted. I think this is a case of checking the machine type
specified in the kernel's ELF header (and that it really is ELF
etc etc).
* Patch tools/libxc/xc_dom_x86.c to remove the
xc_dom_register_arch_hooks call for xc_dom_64.
* Use XSM to deny XEN_DOMCTL_set_address_size (I'm not sure how
this stuff works).
Realistically the only robust way (i.e. the one which you could be most
sure of doing it's job properly with the least possibility of a sneakily
constructed kernel getting around the validation routines etc.) would be
to do it in the hypervisor, at which point you might as well just apply
the fix.
Ian.
^ 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.