test_vmx_intel_x64.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <test.h>
24 
25 using namespace intel_x64;
26 
27 uintptr_t g_region = 0;
28 std::map<vm::field_type, vm::value_type> g_vmcs;
29 
30 bool g_vmxon_fails = false;
31 bool g_vmxoff_fails = false;
32 bool g_vmclear_fails = false;
33 bool g_vmload_fails = false;
34 bool g_vmreset_fails = false;
35 bool g_vmread_fails = false;
36 bool g_vmwrite_fails = false;
37 bool g_vmlaunch_fails = false;
38 bool g_invept_fails = false;
39 bool g_invvpid_fails = false;
40 
41 extern "C" bool
42 __vmxon(void *ptr) noexcept
43 { (void)ptr; return !g_vmxon_fails; }
44 
45 extern "C" bool
47 { return !g_vmxoff_fails; }
48 
49 extern "C" bool
50 __vmclear(void *ptr) noexcept
51 { (void)ptr; return !g_vmclear_fails; }
52 
53 extern "C" bool
54 __vmptrld(void *ptr) noexcept
55 { (void)ptr; return !g_vmload_fails; }
56 
57 extern "C" bool
58 __vmptrst(void *ptr) noexcept
59 { (void)ptr; return !g_vmreset_fails; }
60 
61 extern "C" bool
62 __vmread(uint64_t field, uint64_t *val) noexcept
63 {
64  if (g_vmread_fails)
65  return false;
66 
67  *val = g_vmcs[field];
68 
69  return true;
70 }
71 
72 extern "C" bool
73 __vmwrite(uint64_t field, uint64_t val) noexcept
74 {
75  if (g_vmwrite_fails)
76  return false;
77 
78  g_vmcs[field] = val;
79 
80  return true;
81 }
82 
83 extern "C" bool
85 { return !g_vmlaunch_fails; }
86 
87 extern "C" bool
88 __invept(uint64_t type, void *ptr) noexcept
89 { (void) type; (void) ptr; return !g_invept_fails; }
90 
91 extern "C" bool
92 __invvpid(uint64_t type, void *ptr) noexcept
93 { (void) type; (void) ptr; return !g_invvpid_fails; }
94 
95 void
96 intrinsics_ut::test_vmx_intel_x64_vmxon_nullptr()
97 {
98  void *invalid_ptr = nullptr;
99  this->expect_exception([&] { vmx::on(invalid_ptr); }, ""_ut_ffe);
100 }
101 
102 void
103 intrinsics_ut::test_vmx_intel_x64_vmxon_failure()
104 {
105  auto ___ = gsl::finally([&]
106  { g_vmxon_fails = false; });
107 
108  g_vmxon_fails = true;
109  this->expect_exception([&] { vmx::on(&g_region); }, ""_ut_ree);
110 }
111 
112 void
113 intrinsics_ut::test_vmx_intel_x64_vmxon_success()
114 {
115  this->expect_no_exception([&] { vmx::on(&g_region); });
116 }
117 
118 void
119 intrinsics_ut::test_vmx_intel_x64_vmxoff_failure()
120 {
121  auto ___ = gsl::finally([&]
122  { g_vmxoff_fails = false; });
123 
124  g_vmxoff_fails = true;
125  this->expect_exception([&] { vmx::off(); }, ""_ut_ree);
126 }
127 
128 void
129 intrinsics_ut::test_vmx_intel_x64_vmxoff_success()
130 {
131  this->expect_no_exception([&] { vmx::off(); });
132 }
133 
134 void
135 intrinsics_ut::test_vmx_intel_x64_vmclear_nullptr()
136 {
137  void *invalid_ptr = nullptr;
138  this->expect_exception([&] { vm::clear(invalid_ptr); }, ""_ut_ffe);
139 }
140 
141 void
142 intrinsics_ut::test_vmx_intel_x64_vmclear_failure()
143 {
144  auto ___ = gsl::finally([&]
145  { g_vmclear_fails = false; });
146 
147  g_vmclear_fails = true;
148  this->expect_exception([&] { vm::clear(&g_region); }, ""_ut_ree);
149 }
150 
151 void
152 intrinsics_ut::test_vmx_intel_x64_vmclear_success()
153 {
154  this->expect_no_exception([&] { vm::clear(&g_region); });
155 }
156 
157 void
158 intrinsics_ut::test_vmx_intel_x64_vmload_nullptr()
159 {
160  void *invalid_ptr = nullptr;
161  this->expect_exception([&] { vm::load(invalid_ptr); }, ""_ut_ffe);
162 }
163 
164 void
165 intrinsics_ut::test_vmx_intel_x64_vmload_failure()
166 {
167  auto ___ = gsl::finally([&]
168  { g_vmload_fails = false; });
169 
170  g_vmload_fails = true;
171  this->expect_exception([&] { vm::load(&g_region); }, ""_ut_ree);
172 }
173 
174 void
175 intrinsics_ut::test_vmx_intel_x64_vmload_success()
176 {
177  this->expect_no_exception([&] { vm::load(&g_region); });
178 }
179 
180 void
181 intrinsics_ut::test_vmx_intel_x64_vmreset_nullptr()
182 {
183  void *invalid_ptr = nullptr;
184  this->expect_exception([&] { vm::reset(invalid_ptr); }, ""_ut_ffe);
185 }
186 
187 void
188 intrinsics_ut::test_vmx_intel_x64_vmreset_failure()
189 {
190  auto ___ = gsl::finally([&]
191  { g_vmreset_fails = false; });
192 
193  g_vmreset_fails = true;
194  this->expect_exception([&] { vm::reset(&g_region); }, ""_ut_ree);
195 }
196 
197 void
198 intrinsics_ut::test_vmx_intel_x64_vmreset_success()
199 {
200  this->expect_no_exception([&] { vm::reset(&g_region); });
201 }
202 
203 void
204 intrinsics_ut::test_vmx_intel_x64_vmread_failure()
205 {
206  auto ___ = gsl::finally([&]
207  { g_vmread_fails = false; });
208 
209  g_vmread_fails = true;
210  this->expect_exception([&] { vm::read(10U); }, ""_ut_ree);
211 }
212 
213 void
214 intrinsics_ut::test_vmx_intel_x64_vmwrite_failure()
215 {
216  auto ___ = gsl::finally([&]
217  { g_vmwrite_fails = false; });
218 
219  g_vmwrite_fails = true;
220  this->expect_exception([&] { vm::write(10U, 10U); }, ""_ut_ree);
221 }
222 
223 void
224 intrinsics_ut::test_vmx_intel_x64_vmread_vmwrite_succcess()
225 {
226  auto val = 10UL;
227 
228  this->expect_no_exception([&] { vm::write(10U, val); });
229  this->expect_no_exception([&] { val = vm::read(10U); });
230  this->expect_true(val == 10UL);
231 }
232 
233 void
234 intrinsics_ut::test_vmx_intel_x64_vmlaunch_demote_success()
235 {
236  this->expect_no_exception([&] { vm::launch_demote(); });
237 }
238 
239 void
240 intrinsics_ut::test_vmx_intel_x64_vmlaunch_demote_failure()
241 {
242  auto ___ = gsl::finally([&]
243  { g_vmlaunch_fails = false; });
244 
245  g_vmlaunch_fails = true;
246  this->expect_exception([&] { vm::launch_demote(); }, ""_ut_ree);
247 }
248 
249 void
250 intrinsics_ut::test_vmx_intel_x64_invept()
251 {
253  this->expect_no_exception([&] { vmx::invept_global(); });
254 
255  auto ___ = gsl::finally([&]
256  { g_invept_fails = false; });
257 
258  g_invept_fails = true;
259  this->expect_exception([&] { vmx::invept_single_context(0); }, ""_ut_ree);
260  this->expect_exception([&] { vmx::invept_global(); }, ""_ut_ree);
261 }
262 
263 void
264 intrinsics_ut::test_vmx_intel_x64_invvpid()
265 {
270 
271  auto ___ = gsl::finally([&]
272  { g_invvpid_fails = false; });
273 
274  g_invvpid_fails = true;
275  this->expect_exception([&] { vmx::invvpid_individual_address(0, 0); }, ""_ut_ree);
276  this->expect_exception([&] { vmx::invvpid_single_context(0); }, ""_ut_ree);
277  this->expect_exception([&] { vmx::invvpid_all_contexts(); }, ""_ut_ree);
278  this->expect_exception([&] { vmx::invvpid_single_context_global(0); }, ""_ut_ree);
279 }
void load(gsl::not_null< void *> ptr)
#define expect_exception(f, e)
Definition: unittest.h:162
bool g_vmxoff_fails
void invvpid_all_contexts()
Definition: vmx_intel_x64.h:89
bool __invvpid(uint64_t type, void *ptr) noexcept
bool __vmptrld(void *ptr) noexcept
std::map< vm::field_type, vm::value_type > g_vmcs
bool __vmptrst(void *ptr) noexcept
#define expect_no_exception(f)
Definition: unittest.h:198
void reset(gsl::not_null< void *> ptr)
void clear(gsl::not_null< void *> ptr)
bool g_vmclear_fails
void uint64_t uint64_t uint64_t *rdx noexcept
bool __invept(uint64_t type, void *ptr) noexcept
uintptr_t g_region
bool __vmwrite(uint64_t field, uint64_t val) noexcept
void invvpid_single_context_global(vpid_type vpid)
Definition: vmx_intel_x64.h:96
void write(field_type field, value_type value, name_type name="")
bool __vmlaunch_demote(void) noexcept
bool g_invvpid_fails
bool __vmxon(void *ptr) noexcept
bool g_vmlaunch_fails
bool __vmxoff(void) noexcept
bool g_invept_fails
bool g_vmload_fails
void launch_demote()
bool g_vmread_fails
auto read(field_type field, name_type name="")
void invvpid_individual_address(vpid_type vpid, integer_pointer addr)
Definition: vmx_intel_x64.h:75
void invept_global()
Definition: vmx_intel_x64.h:68
void on(gsl::not_null< void *> ptr)
Definition: vmx_intel_x64.h:49
bool __vmread(uint64_t field, uint64_t *val) noexcept
bool __vmclear(void *ptr) noexcept
bool g_vmreset_fails
void invept_single_context(eptp_type eptp)
Definition: vmx_intel_x64.h:61
bool g_vmwrite_fails
#define expect_true(a)
void invvpid_single_context(vpid_type vpid)
Definition: vmx_intel_x64.h:82
bool g_vmxon_fails