test.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>
23 #include <fstream>
24 #include <sys/mman.h>
25 
26 const auto c_dummy_misc_filename = "../cross/libdummy_misc.so";
27 const auto c_dummy_code_filename = "../cross/libdummy_code.so";
28 
30  m_dummy_misc_length(0),
31  m_dummy_code_length(0)
32 {
33 }
34 
36 {
37  std::ifstream dummy_misc_ifs(c_dummy_misc_filename, std::ifstream::ate);
38  std::ifstream dummy_code_ifs(c_dummy_code_filename, std::ifstream::ate);
39 
40  m_dummy_misc_length = static_cast<uint64_t>(dummy_misc_ifs.tellg());
41  m_dummy_code_length = static_cast<uint64_t>(dummy_code_ifs.tellg());
42 
43  m_dummy_misc = std::make_unique<char[]>(m_dummy_misc_length);
44  m_dummy_code = std::make_unique<char[]>(m_dummy_code_length);
45 
46  dummy_misc_ifs.seekg(0);
47  dummy_code_ifs.seekg(0);
48 
49  dummy_misc_ifs.read(m_dummy_misc.get(), static_cast<int64_t>(m_dummy_misc_length));
50  dummy_code_ifs.read(m_dummy_code.get(), static_cast<int64_t>(m_dummy_code_length));
51 
52  return true;
53 }
54 
56 {
57  return true;
58 }
59 
61 {
62  this->test_bfelf_file_init_success();
63  this->test_bfelf_file_init_invalid_file_arg();
64  this->test_bfelf_file_init_invalid_file_size_arg();
65  this->test_bfelf_file_init_invalid_elf_file();
66  this->test_bfelf_file_init_invalid_magic_0();
67  this->test_bfelf_file_init_invalid_magic_1();
68  this->test_bfelf_file_init_invalid_magic_2();
69  this->test_bfelf_file_init_invalid_magic_3();
70  this->test_bfelf_file_init_invalid_class();
71  this->test_bfelf_file_init_invalid_data();
72  this->test_bfelf_file_init_invalid_ident_version();
73  this->test_bfelf_file_init_invalid_osabi();
74  this->test_bfelf_file_init_invalid_abiversion();
75  this->test_bfelf_file_init_invalid_type();
76  this->test_bfelf_file_init_invalid_machine();
77  this->test_bfelf_file_init_invalid_version();
78  this->test_bfelf_file_init_invalid_flags();
79 
80  this->test_bfelf_file_get_num_load_instrs_invalid_ef();
81  this->test_bfelf_file_get_num_load_instrs_uninitalized();
82  this->test_bfelf_file_get_num_load_instrs_success();
83 
84  this->test_bfelf_file_get_load_instr_invalid_ef();
85  this->test_bfelf_file_get_load_instr_invalid_index();
86  this->test_bfelf_file_get_load_instr_invalid_instr();
87  this->test_bfelf_file_get_load_instr_success();
88 
89  this->test_bfelf_loader_add_invalid_loader();
90  this->test_bfelf_loader_add_invalid_elf_file();
91  this->test_bfelf_loader_add_invalid_addr();
92  this->test_bfelf_loader_add_too_many_files();
93  this->test_bfelf_loader_add_fake();
94 
95  this->test_bfelf_loader_relocate_invalid_loader();
96  this->test_bfelf_loader_relocate_no_files_added();
97  this->test_bfelf_loader_relocate_uninitialized_files();
98  this->test_bfelf_loader_relocate_twice();
99  this->test_bfelf_loader_relocate_no_symbol();
100 
101  this->test_bfelf_file_get_section_info_invalid_elf_file();
102  this->test_bfelf_file_get_section_info_invalid_info();
103  this->test_bfelf_file_get_section_info_expected_misc_resources();
104  this->test_bfelf_file_get_section_info_expected_code_resources();
105  this->test_bfelf_file_get_section_info_init_fini();
106 
107  this->test_bfelf_loader_resolve_symbol_invalid_loader();
108  this->test_bfelf_loader_resolve_symbol_invalid_name();
109  this->test_bfelf_loader_resolve_symbol_invalid_addr();
110  this->test_bfelf_loader_resolve_symbol_no_files_added();
111  this->test_bfelf_loader_resolve_symbol_uninitialized_files();
112  this->test_bfelf_loader_resolve_no_such_symbol();
113  this->test_bfelf_loader_resolve_symbol_success();
114  this->test_bfelf_loader_resolve_no_such_symbol_no_hash();
115  this->test_bfelf_loader_resolve_symbol_success_no_hash();
116  this->test_bfelf_loader_resolve_symbol_real_test();
117 
118  this->test_bfelf_file_get_entry_invalid_ef();
119  this->test_bfelf_file_get_entry_invalid_addr();
120  this->test_bfelf_file_get_entry_success();
121 
122  this->test_bfelf_file_get_stack_perm_invalid_ef();
123  this->test_bfelf_file_get_stack_perm_invalid_addr();
124  this->test_bfelf_file_get_stack_perm_success();
125 
126  this->test_bfelf_file_get_relro_invalid_ef();
127  this->test_bfelf_file_get_relro_invalid_addr();
128  this->test_bfelf_file_get_relro_invalid_size();
129  this->test_bfelf_file_get_relro_success();
130 
131  this->test_bfelf_file_get_num_needed_invalid_ef();
132  this->test_bfelf_file_get_num_needed_success();
133 
134  this->test_bfelf_file_get_needed_invalid_ef();
135  this->test_bfelf_file_get_needed_invalid_index();
136  this->test_bfelf_file_get_needed_invalid_size();
137  this->test_bfelf_file_get_needed_success();
138 
139  this->test_bfelf_file_get_total_size_invalid_ef();
140  this->test_bfelf_file_get_total_size_success();
141 
142  this->test_bfelf_file_get_pic_pie_invalid_ef();
143  this->test_bfelf_file_get_pic_pie_success();
144 
145  this->test_private_hash();
146  this->test_private_relocate_invalid_relocation_dyn();
147  this->test_private_relocate_invalid_relocation_plt();
148  this->test_private_process_dynamic_section();
149 
150  return true;
151 }
152 
153 char *
155 {
156  auto addr = malloc(size);
157 
158  auto &&addr_adjusted = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(addr) & 0xFFFFFFFFFFFFF000);
159  auto &&size_adjusted = size + (reinterpret_cast<uintptr_t>(addr) & 0xFFF);
160 
161  memset(addr, 0, size);
162  mprotect(addr_adjusted, size_adjusted, PROT_READ | PROT_WRITE | PROT_EXEC);
163 
164  return reinterpret_cast<char *>(addr);
165 }
166 
167 std::pair<std::unique_ptr<char[]>, uint64_t>
168 bfelf_loader_ut::get_elf_exec(bfelf_file_t *ef)
169 {
170  auto &&total = static_cast<size_t>(bfelf_file_get_total_size(ef));
171  auto &&num_segments = bfelf_file_get_num_load_instrs(ef);
172 
173  auto &&exec = std::unique_ptr<char[]>(alloc_exec(total));
174 
175  for (auto i = 0U; i < num_segments; i++)
176  {
177  auto &&ret = 0L;
178  bfelf_load_instr *instr = nullptr;
179 
180  ret = bfelf_file_get_load_instr(ef, i, &instr);
181  (void) ret;
182 
183  auto &&exec_view = gsl::make_span(exec, gsl::narrow_cast<std::ptrdiff_t>(total));
184  auto &&file_view = gsl::make_span(ef->file, gsl::narrow_cast<std::ptrdiff_t>(ef->filesz));
185 
186  memcpy(&exec_view.at(instr->mem_offset), &file_view.at(instr->file_offset), instr->filesz);
187  }
188 
189  return {std::move(exec), total};
190 }
191 
192 #define offset(a,b) ( (reinterpret_cast<uintptr_t>(&(a))) - (reinterpret_cast<uintptr_t>(&(b))) )
193 
194 std::pair<std::unique_ptr<char[]>, uint64_t>
195 bfelf_loader_ut::get_test()
196 {
197  auto &&size = sizeof(bfelf_test);
198  auto &&buff = std::make_unique<char[]>(size);
199  auto &&test = reinterpret_cast<bfelf_test *>(buff.get());
200 
201  test->header.e_ident[bfei_mag0] = 0x7F;
202  test->header.e_ident[bfei_mag1] = 'E';
203  test->header.e_ident[bfei_mag2] = 'L';
204  test->header.e_ident[bfei_mag3] = 'F';
205  test->header.e_ident[bfei_class] = bfelfclass64;
206  test->header.e_ident[bfei_data] = bfelfdata2lsb;
207  test->header.e_ident[bfei_version] = bfev_current;
208  test->header.e_ident[bfei_osabi] = bfelfosabi_sysv;
209  test->header.e_ident[bfei_abiversion] = 0;
210  test->header.e_type = bfet_dyn;
211  test->header.e_machine = bfem_x86_64;
212  test->header.e_version = bfev_current;
213  test->header.e_entry = 0x150;
214  test->header.e_phoff = offset(test->phdrtab, *test);
215  test->header.e_shoff = offset(test->shdrtab, *test);
216  test->header.e_flags = 0;
217  test->header.e_ehsize = sizeof(bfelf_ehdr);
218  test->header.e_phentsize = sizeof(bfelf_phdr);
219  test->header.e_phnum = sizeof(test_phdrtab) / sizeof(bfelf_phdr);
220  test->header.e_shentsize = sizeof(bfelf_shdr);
221  test->header.e_shnum = sizeof(test_shdrtab) / sizeof(bfelf_shdr);
222  test->header.e_shstrndx = 2;
223 
224  test->phdrtab.re_segment.p_type = bfpt_load;
225  test->phdrtab.re_segment.p_flags = bfpf_r | bfpf_x;
226  test->phdrtab.re_segment.p_offset = 0;
227  test->phdrtab.re_segment.p_vaddr = 0;
228  test->phdrtab.re_segment.p_paddr = 0;
229  test->phdrtab.re_segment.p_filesz = 0x500;
230  test->phdrtab.re_segment.p_memsz = 0x500;
231  test->phdrtab.re_segment.p_align = 0x1000;
232 
233  test->phdrtab.rw_segment.p_type = bfpt_load;
234  test->phdrtab.rw_segment.p_flags = bfpf_r | bfpf_w;
235  test->phdrtab.rw_segment.p_offset = 0x500;
236  test->phdrtab.rw_segment.p_vaddr = 0x500;
237  test->phdrtab.rw_segment.p_paddr = 0x500;
238  test->phdrtab.rw_segment.p_filesz = 0x500;
239  test->phdrtab.rw_segment.p_memsz = 0x500;
240  test->phdrtab.rw_segment.p_align = 0x1000;
241 
242  test->phdrtab.dyn_segment.p_type = bfpt_dynamic;
243  test->phdrtab.dyn_segment.p_flags = bfpf_r | bfpf_w;
244  test->phdrtab.dyn_segment.p_offset = offset(test->dynamic, *test);
245  test->phdrtab.dyn_segment.p_vaddr = 0x0;
246  test->phdrtab.dyn_segment.p_paddr = 0x0;
247  test->phdrtab.dyn_segment.p_filesz = sizeof(test_dynamic);
248  test->phdrtab.dyn_segment.p_memsz = sizeof(test_dynamic);
249  test->phdrtab.dyn_segment.p_align = 0x1000;
250 
251  test->phdrtab.stack_segment.p_type = bfpt_gnu_stack;
252  test->phdrtab.stack_segment.p_flags = bfpf_r | bfpf_w;
253  test->phdrtab.stack_segment.p_offset = 0x0;
254  test->phdrtab.stack_segment.p_vaddr = 0x0;
255  test->phdrtab.stack_segment.p_paddr = 0x0;
256  test->phdrtab.stack_segment.p_filesz = 0x0;
257  test->phdrtab.stack_segment.p_memsz = 0x0;
258  test->phdrtab.stack_segment.p_align = 0x0;
259 
260  test->phdrtab.relro_segment.p_type = bfpt_gnu_relro;
261  test->phdrtab.relro_segment.p_flags = bfpf_r;
262  test->phdrtab.relro_segment.p_offset = 0x0;
263  test->phdrtab.relro_segment.p_vaddr = 0x0;
264  test->phdrtab.relro_segment.p_paddr = 0x0;
265  test->phdrtab.relro_segment.p_filesz = 0x500;
266  test->phdrtab.relro_segment.p_memsz = 0x500;
267  test->phdrtab.relro_segment.p_align = 0x1000;
268 
269  test->dynamic.needed1.d_tag = bfdt_needed;
270  test->dynamic.needed2.d_tag = bfdt_needed;
271  test->dynamic.pltgot.d_tag = bfdt_pltgot;
272  test->dynamic.strtab.d_tag = bfdt_strtab;
273  test->dynamic.strtab.d_val = offset(test->dynstr, *test);
274  test->dynamic.symtab.d_tag = bfdt_symtab;
275  test->dynamic.symtab.d_val = offset(test->dynsym, *test);
276  test->dynamic.rela.d_tag = bfdt_rela;
277  test->dynamic.rela.d_val = offset(test->relatab, *test);
278  test->dynamic.relasz.d_tag = bfdt_relasz;
279  test->dynamic.relasz.d_val = sizeof(test_relatab);
280  test->dynamic.relaent.d_tag = bfdt_relaent;
281  test->dynamic.relaent.d_val = sizeof(bfelf_rela);
282  test->dynamic.strsz.d_tag = bfdt_strsz;
283  test->dynamic.strsz.d_val = sizeof(test_dynstr);
284  test->dynamic.init.d_tag = bfdt_init;
285  test->dynamic.init.d_val = offset(test->init_array, *test);
286  test->dynamic.fini.d_tag = bfdt_fini;
287  test->dynamic.fini.d_val = offset(test->fini_array, *test);
288  test->dynamic.init_array.d_tag = bfdt_init_array;
289  test->dynamic.init_array.d_val = offset(test->init_array, *test);
290  test->dynamic.fini_array.d_tag = bfdt_fini_array;
291  test->dynamic.fini_array.d_val = offset(test->fini_array, *test);
292  test->dynamic.init_array.d_tag = bfdt_init_arraysz;
293  test->dynamic.init_array.d_val = sizeof(test_init_array);
294  test->dynamic.fini_array.d_tag = bfdt_fini_arraysz;
295  test->dynamic.fini_array.d_val = sizeof(test_fini_array);
296  test->dynamic.flags_1.d_tag = bfdt_flags_1;
297  test->dynamic.last.d_tag = bfdt_null;
298 
299  test->shdrtab.eh_frame.sh_name = 0x0;
300  test->shdrtab.eh_frame.sh_type = bfsht_strtab;
301  test->shdrtab.eh_frame.sh_flags = 0;
302  test->shdrtab.eh_frame.sh_addr = 0x250;
303  test->shdrtab.eh_frame.sh_offset = offset(test->eh_frame, *test);
304  test->shdrtab.eh_frame.sh_size = sizeof(test_eh_frame);
305  test->shdrtab.eh_frame.sh_link = 0;
306  test->shdrtab.eh_frame.sh_addralign = 1;
307  test->shdrtab.eh_frame.sh_entsize = 0;
308 
309  test->shdrtab.dynstr.sh_offset = offset(test->dynstr, *test);
310 
311  test->shdrtab.eh_frame.sh_name = 10;
312  test->shdrtab.ctors.sh_name = 20;
313  test->shdrtab.dtors.sh_name = 30;
314 
315  strncpy(static_cast<char *>(test->dynstr.str2), ".eh_frame", 10);
316  strncpy(static_cast<char *>(test->dynstr.str3), ".ctors", 10);
317  strncpy(static_cast<char *>(test->dynstr.str4), ".dtors", 10);
318 
319  return {std::move(buff), size};
320 }
321 
322 int
323 main(int argc, char *argv[])
324 {
326 }
void * memset(void *block, int c, size_t size)
int main(int argc, char *argv[])
Definition: test.cpp:221
void * malloc(size_t size)
Definition: syscall.cpp:364
bfelf64_off mem_offset
Definition: bfelf_loader.h:210
bool fini() override
Definition: test.cpp:55
bool list() override
Definition: test.cpp:60
bfelf64_off file_offset
Definition: bfelf_loader.h:211
constexpr const auto size
bfelf_ehdr header
Definition: test_elf.h:122
constexpr const auto addr
Definition: cpuid_x64.h:80
#define RUN_ALL_TESTS(ut)
Definition: unittest.h:246
bool init() override
Definition: test.cpp:35
char * alloc_exec(size_t size)
Definition: test.cpp:154
bfelf64_xword filesz
Definition: bfelf_loader.h:213
const auto c_dummy_misc_filename
Definition: test.cpp:31
bfelf_loader_ut()
Definition: test.cpp:29
#define offset(a, b)
Definition: test.cpp:192
const auto c_dummy_code_filename
Definition: test.cpp:27