Xen Test Framework
main.c
Go to the documentation of this file.
1 
24 #include <xtf.h>
25 
26 const char test_title[] = "XSA-278 PoC";
27 
28 static exinfo_t stub_vmclear(void)
29 {
30  exinfo_t ex = 0;
31  uint64_t addr = 0;
32 
33  asm volatile ("1: vmclear %[ptr]; 2:"
34  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
35  : "+D" (ex)
36  : [ptr] "m" (addr),
37  [rec] "p" (ex_record_fault_edi));
38 
39  return ex;
40 }
41 
42 static exinfo_t stub_vmptrld(void)
43 {
44  exinfo_t ex = 0;
45  uint64_t addr = 0;
46 
47  asm volatile ("1: vmptrld %[ptr]; 2:"
48  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
49  : "+D" (ex)
50  : [ptr] "m" (addr),
51  [rec] "p" (ex_record_fault_edi));
52 
53  return ex;
54 }
55 
56 static exinfo_t stub_vmptrst(void)
57 {
58  exinfo_t ex = 0;
59  uint64_t addr;
60 
61  asm volatile ("1: vmptrst %[ptr]; 2:"
62  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
63  : "+D" (ex), [ptr] "=m" (addr)
64  : [rec] "p" (ex_record_fault_edi));
65 
66  return ex;
67 }
68 
69 static exinfo_t stub_vmread(void)
70 {
71  exinfo_t ex = 0;
72  unsigned long tmp;
73 
74  asm volatile ("1: vmread %[field], %[value]; 2:"
75  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
76  : "+D" (ex), [value] "=rm" (tmp)
77  : [field] "r" (0l),
78  [rec] "p" (ex_record_fault_edi));
79 
80  return ex;
81 }
82 
83 static exinfo_t stub_vmwrite(void)
84 {
85  exinfo_t ex = 0;
86 
87  asm volatile ("1: vmwrite %[value], %[field]; 2:"
88  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
89  : "+D" (ex)
90  : [field] "r" (0l), [value] "rm" (0l),
91  [rec] "p" (ex_record_fault_edi));
92 
93  return ex;
94 }
95 
96 static exinfo_t stub_vmlaunch(void)
97 {
98  exinfo_t ex = 0;
99 
100  asm volatile ("1: vmlaunch; 2:"
101  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
102  : "+D" (ex)
103  : [rec] "p" (ex_record_fault_edi));
104 
105  return ex;
106 }
107 
109 {
110  exinfo_t ex = 0;
111 
112  asm volatile ("1: vmresume; 2:"
113  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
114  : "+D" (ex)
115  : [rec] "p" (ex_record_fault_edi));
116 
117  return ex;
118 }
119 
120 static exinfo_t stub_vmxoff(void)
121 {
122  exinfo_t ex = 0;
123 
124  asm volatile ("1: vmxoff; 2:"
125  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
126  : "+D" (ex)
127  : [rec] "p" (ex_record_fault_edi));
128 
129  return ex;
130 }
131 
132 static exinfo_t stub_vmxon(void)
133 {
134  exinfo_t ex = 0;
135  uint64_t addr = ~0ull;
136 
137  asm volatile ("1: vmxon %[ptr]; 2:"
138  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
139  : "+D" (ex)
140  : [ptr] "m" (addr),
141  [rec] "p" (ex_record_fault_edi));
142 
143  return ex;
144 }
145 
146 static exinfo_t stub_invept(void)
147 {
148  exinfo_t ex = 0;
149  struct { uint64_t eptp, rsvd; } desc;
150 
151  asm volatile ("1: invept %[desc], %[type]; 2:"
152  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
153  : "+D" (ex)
154  : [type] "r" (0l), [desc] "m" (desc),
155  [rec] "p" (ex_record_fault_edi));
156 
157  return ex;
158 }
159 
160 static exinfo_t stub_invvpid(void)
161 {
162  exinfo_t ex = 0;
163  struct { uint64_t vpid, linear; } desc;
164 
165  asm volatile ("1: invvpid %[desc], %[type]; 2:"
166  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
167  : "+D" (ex)
168  : [type] "r" (0l), [desc] "m" (desc),
169  [rec] "p" (ex_record_fault_edi));
170 
171  return ex;
172 }
173 
174 static const struct test {
175  const char *name;
176  exinfo_t (*fn)(void);
177 } tests[] = {
178  /* VMCS maintenance */
179  { "vmclear", stub_vmclear },
180  { "vmptrld", stub_vmptrld },
181  { "vmptrst", stub_vmptrst },
182  { "vmread", stub_vmread },
183  { "vmwrite", stub_vmwrite },
184 
185  /* VMX management */
186  { "vmlaunch", stub_vmlaunch },
187  { "vmresume", stub_vmresume },
188  { "vmxoff", stub_vmxoff },
189  { "vmxon", stub_vmxon },
190 
191  /* TLB Management */
192  { "invept", stub_invept },
193  { "invvpid", stub_invvpid },
194 };
195 
196 void test_main(void)
197 {
198  unsigned int i;
199  unsigned long cr4 = read_cr4();
200 
201  if ( cr4 & X86_CR4_VMXE )
202  {
203  xtf_error("Error: CR4.VMXE found unexpectedly set\n");
204  write_cr4(cr4 & ~X86_CR4_VMXE);
205  }
206 
207  for ( i = 0; i < ARRAY_SIZE(tests); ++i )
208  {
209  const struct test *t = &tests[i];
210  exinfo_t ex = t->fn();
211 
212  if ( ex != EXINFO_SYM(UD, 0) )
213  xtf_failure("Fail: %s, got %pe, expected #UD\n",
214  t->name, _p(ex));
215  }
216 
217  if ( !cpu_has_vmx && !write_cr4_safe(cr4 | X86_CR4_VMXE) )
218  xtf_failure("Fail: CR4.VMXE settable without feature\n");
219 
220  xtf_success("Success: Probably not vulnerable to XSA-278\n");
221 }
222 
223 /*
224  * Local variables:
225  * mode: C
226  * c-file-style: "BSD"
227  * c-basic-offset: 4
228  * tab-width: 4
229  * indent-tabs-mode: nil
230  * End:
231  */
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
static exinfo_t stub_vmxon(void)
Definition: main.c:132
name
Definition: mkcfg.py:15
static exinfo_t stub_vmclear(void)
Definition: main.c:28
#define ARRAY_SIZE(a)
Definition: lib.h:8
bool ex_record_fault_edi(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %edi.
Definition: extable.c:16
static exinfo_t stub_invept(void)
Definition: main.c:146
static exinfo_t stub_vmptrld(void)
Definition: main.c:42
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
static exinfo_t stub_vmread(void)
Definition: main.c:69
static exinfo_t stub_vmxoff(void)
Definition: main.c:120
#define cpu_has_vmx
Definition: cpuid.h:77
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:137
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
#define X86_CR4_VMXE
Definition: processor.h:56
static unsigned long read_cr4(void)
Definition: lib.h:252
static exinfo_t stub_vmwrite(void)
Definition: main.c:83
const char test_title[]
The title of the test.
Definition: main.c:14
static void write_cr4(unsigned long cr4)
Definition: lib.h:285
static bool write_cr4_safe(unsigned long cr4)
Definition: lib.h:290
const char * name
Definition: main.c:41
static exinfo_t stub_vmptrst(void)
Definition: main.c:56
Definition: main.c:38
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define EXINFO_SYM(exc, ec)
Definition: exinfo.h:29
void xtf_error(const char *fmt,...)
Report a test error.
Definition: report.c:80
static const struct test tests[]
static exinfo_t stub_vmresume(void)
Definition: main.c:108
unsigned long(* fn)(unsigned long)
Definition: main.c:40
static exinfo_t stub_vmlaunch(void)
Definition: main.c:96
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
static exinfo_t stub_invvpid(void)
Definition: main.c:160