test_memory_manager_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 <gsl/gsl>
23 
24 #include <vector>
25 
26 #include <test.h>
27 #include <memory.h>
30 
31 #include <intrinsics/x64.h>
32 using namespace x64;
33 
34 extern "C" int64_t
36 
37 void
38 memory_manager_ut::test_memory_manager_x64_size_out_of_bounds()
39 {
40  this->expect_true(g_mm->size(nullptr) == 0);
41  this->expect_true(g_mm->size(make_ptr(0xFFFFFFFFFFFFFF00)) == 0);
42  this->expect_true(g_mm->size_map(nullptr) == 0);
43  this->expect_true(g_mm->size_map(make_ptr(0xFFFFFFFFFFFFFF00)) == 0);
44 }
45 
46 void
47 memory_manager_ut::test_memory_manager_x64_malloc_out_of_memory()
48 {
49  this->expect_true(g_mm->alloc(0) == nullptr);
50  this->expect_true(g_mm->alloc_map(0) == nullptr);
51 
52  this->expect_true(g_mm->alloc(0xFFFFFFFFFFFFFF00) == nullptr);
53  this->expect_true(g_mm->alloc_map(0xFFFFFFFFFFFFFF00) == nullptr);
54 }
55 
56 void
57 memory_manager_ut::test_memory_manager_x64_malloc_heap()
58 {
59  auto &&ptr = g_mm->alloc(cache_line_size);
60 
61  this->expect_true(ptr != nullptr);
62  this->expect_true(g_mm->size(ptr) == cache_line_size);
63 
64  g_mm->free(ptr);
65 }
66 
67 void
68 memory_manager_ut::test_memory_manager_x64_malloc_page()
69 {
70  auto &&ptr = g_mm->alloc(page_size);
71 
72  this->expect_true(ptr != nullptr);
73  this->expect_true(g_mm->size(ptr) == page_size);
74 
75  g_mm->free(ptr);
76 }
77 
78 void
79 memory_manager_ut::test_memory_manager_x64_malloc_map()
80 {
81  auto &&ptr = g_mm->alloc_map(page_size);
82 
83  this->expect_true(ptr != nullptr);
84  this->expect_true(g_mm->size_map(ptr) == page_size);
85 
86  g_mm->free_map(ptr);
87 }
88 
89 void
90 memory_manager_ut::test_memory_manager_x64_add_md()
91 {
92  memory_descriptor md = {0, 0, 0};
93 
94  this->expect_true(add_md(nullptr) == MEMORY_MANAGER_FAILURE);
96 }
97 
98 void
99 memory_manager_ut::test_memory_manager_x64_add_md_invalid_type()
100 {
102  memory_manager_x64::integer_pointer phys = 0x54321000;
104 
105  this->expect_exception([&] { g_mm->add_md(virt, phys, attr); }, ""_ut_ffe);
106  this->expect_true(g_mm->descriptors().empty());
107 }
108 
109 void
110 memory_manager_ut::test_memory_manager_x64_add_md_unaligned_physical()
111 {
112  memory_manager_x64::integer_pointer virt = 0x12345000;
113  memory_manager_x64::integer_pointer phys = 0x54321123;
115 
116  this->expect_exception([&] { g_mm->add_md(virt, phys, attr); }, ""_ut_ffe);
117  this->expect_true(g_mm->descriptors().empty());
118 }
119 
120 void
121 memory_manager_ut::test_memory_manager_x64_add_md_unaligned_virtual()
122 {
123  memory_manager_x64::integer_pointer virt = 0x12345123;
124  memory_manager_x64::integer_pointer phys = 0x54321000;
126 
127  this->expect_exception([&] { g_mm->add_md(virt, phys, attr); }, ""_ut_ffe);
128  this->expect_true(g_mm->descriptors().empty());
129 }
130 
131 void
132 memory_manager_ut::test_memory_manager_x64_remove_md_invalid_virt()
133 {
134  memory_manager_x64::integer_pointer virt = 0x12345000;
135  memory_manager_x64::integer_pointer phys = 0x54321000;
137 
138  this->expect_no_exception([&] { g_mm->add_md(virt, phys, attr); });
139  this->expect_false(g_mm->descriptors().empty());
140 
141  this->expect_no_exception([&] { g_mm->remove_md(0); });
142  this->expect_no_exception([&] { g_mm->remove_md(virt + 0x10); });
143  this->expect_no_exception([&] { g_mm->remove_md(virt); });
144  this->expect_true(g_mm->descriptors().empty());
145 }
146 
147 void
148 memory_manager_ut::test_memory_manager_x64_virtint_to_physint_failure()
149 {
150  this->expect_exception([&] { g_mm->virtint_to_physint(0); }, ""_ut_ffe);
151  this->expect_exception([&] { g_mm->virtint_to_physint(0x54321000); }, ""_ut_ore);
152 }
153 
154 void
155 memory_manager_ut::test_memory_manager_x64_physint_to_virtint_failure()
156 {
157  this->expect_exception([&] { g_mm->physint_to_virtint(0); }, ""_ut_ffe);
158  this->expect_exception([&] { g_mm->physint_to_virtint(0x12346000); }, ""_ut_ore);
159 }
160 
161 void
162 memory_manager_ut::test_memory_manager_x64_virtint_to_attrint_failure()
163 {
164  this->expect_exception([&] { g_mm->virtint_to_attrint(0); }, ""_ut_ffe);
165  this->expect_exception([&] { g_mm->virtint_to_attrint(0x54321000); }, ""_ut_ore);
166 }
167 
168 template<class F> auto test_with_md(F f)
169 {
170  auto &&ret = false;
171  memory_manager_x64::integer_pointer virt = 0x12345000;
172  memory_manager_x64::integer_pointer phys = 0x54321000;
174 
175  {
176  g_mm->add_md(virt, phys, attr);
177 
178  auto ___ = gsl::finally([&]
179  { g_mm->remove_md(virt); });
180 
181  ret = f();
182  }
183 
184  return ret && g_mm->descriptors().empty();
185 }
186 
187 void
188 memory_manager_ut::test_memory_manager_x64_virtint_to_physint_random_address()
189 {
190  this->expect_true(test_with_md([&] { return g_mm->virtint_to_physint(0x12345ABC) == 0x54321ABC; }));
191  this->expect_true(test_with_md([&] { return g_mm->virtint_to_physint(0x12345FFF) == 0x54321FFF; }));
192  this->expect_true(test_with_md([&] { return g_mm->virtint_to_physint(0x12345000) == 0x54321000; }));
193 }
194 
195 void
196 memory_manager_ut::test_memory_manager_x64_virtint_to_physint_nullptr()
197 {
198  this->expect_exception([&] { g_mm->virtint_to_physint(0); }, ""_ut_ffe);
199  this->expect_exception([&] { g_mm->virtptr_to_physint(nullptr); }, ""_ut_ffe);
200  this->expect_exception([&] { g_mm->virtint_to_physptr(0); }, ""_ut_ffe);
201  this->expect_exception([&] { g_mm->virtptr_to_physptr(nullptr); }, ""_ut_ffe);
202 }
203 
204 void
205 memory_manager_ut::test_memory_manager_x64_physint_to_virtint_random_address()
206 {
207  this->expect_true(test_with_md([&] { return g_mm->physint_to_virtint(0x54321ABC) == 0x12345ABC; }));
208  this->expect_true(test_with_md([&] { return g_mm->physint_to_virtint(0x54321FFF) == 0x12345FFF; }));
209  this->expect_true(test_with_md([&] { return g_mm->physint_to_virtint(0x54321000) == 0x12345000; }));
210 }
211 
212 void
213 memory_manager_ut::test_memory_manager_x64_physint_to_virtint_nullptr()
214 {
215  this->expect_exception([&] { g_mm->physint_to_virtint(0); }, ""_ut_ffe);
216  this->expect_exception([&] { g_mm->physptr_to_virtint(nullptr); }, ""_ut_ffe);
217  this->expect_exception([&] { g_mm->physint_to_virtptr(0); }, ""_ut_ffe);
218  this->expect_exception([&] { g_mm->physptr_to_virtptr(nullptr); }, ""_ut_ffe);
219 }
220 
221 void
222 memory_manager_ut::test_memory_manager_x64_virtint_to_attrint_random_address()
223 {
224  this->expect_true(test_with_md([&] { return g_mm->virtint_to_attrint(0x12345ABC) == (MEMORY_TYPE_R | MEMORY_TYPE_W | MEMORY_TYPE_E); }));
225  this->expect_true(test_with_md([&] { return g_mm->virtint_to_attrint(0x12345FFF) == (MEMORY_TYPE_R | MEMORY_TYPE_W | MEMORY_TYPE_E); }));
226  this->expect_true(test_with_md([&] { return g_mm->virtint_to_attrint(0x12345000) == (MEMORY_TYPE_R | MEMORY_TYPE_W | MEMORY_TYPE_E); }));
227 }
228 
229 void
230 memory_manager_ut::test_memory_manager_x64_virtint_to_attrint_nullptr()
231 {
232  this->expect_exception([&] { g_mm->virtint_to_attrint(0); }, ""_ut_ffe);
233  this->expect_exception([&] { g_mm->virtptr_to_attrint(nullptr); }, ""_ut_ffe);
234 }
#define expect_exception(f, e)
Definition: unittest.h:162
auto test_with_md(F f)
constexpr const auto cache_line_size
Definition: x64.h:37
#define MEMORY_TYPE_E
Definition: memory.h:41
#define MEMORY_TYPE_W
Definition: memory.h:40
#define expect_no_exception(f)
Definition: unittest.h:198
#define MEMORY_MANAGER_FAILURE
Definition: error_codes.h:99
#define MEMORY_TYPE_R
Definition: memory.h:39
void uint64_t uint64_t uint64_t *rdx noexcept
auto make_ptr(const T ptr)
Definition: unittest.h:77
decltype(memory_descriptor::type) attr_type
int64_t add_md(struct memory_descriptor *md) noexcept
constexpr page_table_x64::integer_pointer virt
#define g_mm
constexpr const auto page_size
Definition: x64.h:35
#define expect_false(a)
Definition: cache_x64.h:31
#define expect_true(a)