1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "UnwinderComponentCreator.h"
18
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <vector>
23
GetRegisters(ArchEnum arch)24 std::unique_ptr<Regs> GetRegisters(ArchEnum arch) {
25 switch (arch) {
26 case unwindstack::ARCH_ARM: {
27 std::unique_ptr<unwindstack::RegsArm> regs = std::make_unique<unwindstack::RegsArm>();
28 return regs;
29 }
30 case unwindstack::ARCH_ARM64: {
31 std::unique_ptr<unwindstack::RegsArm64> regs = std::make_unique<unwindstack::RegsArm64>();
32 return regs;
33 }
34 case unwindstack::ARCH_RISCV64: {
35 std::unique_ptr<unwindstack::RegsRiscv64> regs = std::make_unique<unwindstack::RegsRiscv64>();
36 return regs;
37 }
38 case unwindstack::ARCH_X86_64: {
39 std::unique_ptr<unwindstack::RegsX86_64> regs = std::make_unique<unwindstack::RegsX86_64>();
40 return regs;
41 }
42 case unwindstack::ARCH_UNKNOWN:
43 default: {
44 std::unique_ptr<unwindstack::RegsX86_64> regs = std::make_unique<unwindstack::RegsX86_64>();
45 return regs;
46 }
47 }
48 }
49
GetArch(FuzzedDataProvider * data_provider)50 ArchEnum GetArch(FuzzedDataProvider* data_provider) {
51 uint8_t arch = data_provider->ConsumeIntegralInRange<uint8_t>(1, kArchCount);
52 return static_cast<ArchEnum>(arch);
53 }
54
ElfAddMapInfo(Maps * maps,uint64_t start,uint64_t end,uint64_t offset,uint64_t flags,const char * name,Elf * elf=nullptr)55 void ElfAddMapInfo(Maps* maps, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
56 const char* name, Elf* elf = nullptr) {
57 std::string str_name(name);
58 maps->Add(start, end, offset, flags, name, static_cast<uint64_t>(-1));
59 if (elf != nullptr) {
60 const auto& map_info = *--maps->end();
61 map_info->set_elf(elf);
62 }
63 }
64
ElfPushFakeFunctionData(FuzzedDataProvider * data_provider,ElfInterfaceFake * elf)65 void ElfPushFakeFunctionData(FuzzedDataProvider* data_provider, ElfInterfaceFake* elf) {
66 uint8_t func_count = data_provider->ConsumeIntegralInRange<uint>(0, kMaxFuncCount);
67 for (uint8_t i = 0; i < func_count; i++) {
68 std::string func_name = data_provider->ConsumeRandomLengthString(kMaxFuncNameLen);
69 bool global = data_provider->ConsumeBool();
70 if (global) {
71 elf->FakeSetGlobalVariable(func_name, data_provider->ConsumeIntegral<uint64_t>());
72 } else {
73 ElfInterfaceFake::FakePushFunctionData(FunctionData(func_name, i));
74 }
75 }
76 }
ElfPushFakeStepData(FuzzedDataProvider * data_provider)77 void ElfPushFakeStepData(FuzzedDataProvider* data_provider) {
78 uint8_t step_count = data_provider->ConsumeIntegralInRange<uint>(0, kMaxStepCount);
79 for (uint8_t i = 0; i < step_count; i++) {
80 uint64_t pc = data_provider->ConsumeIntegral<uint64_t>();
81 uint64_t sp = data_provider->ConsumeIntegral<uint64_t>();
82 bool finished = i + 1 == step_count;
83 ElfInterfaceFake::FakePushStepData(StepData(pc, sp, finished));
84 }
85 }
86
PopulateElfFake(FuzzedDataProvider * data_provider)87 ElfFake* PopulateElfFake(FuzzedDataProvider* data_provider) {
88 // This will be passed to a smart pointer in ElfAddMapInfo.
89 std::shared_ptr<Memory> memory(new MemoryFake);
90 ElfFake* elf = new ElfFake(memory);
91
92 // This will be handled by a smart pointer within Elf.
93 std::shared_ptr<Memory> empty;
94 ElfInterfaceFake* interface_fake = new ElfInterfaceFake(empty);
95 std::string build_id = data_provider->ConsumeRandomLengthString(kMaxBuildIdLen);
96 interface_fake->FakeSetBuildID(build_id);
97 std::string so_name = data_provider->ConsumeRandomLengthString(kMaxSoNameLen);
98 interface_fake->FakeSetSoname(so_name.c_str());
99
100 elf->FakeSetArch(GetArch(data_provider));
101 elf->FakeSetLoadBias(data_provider->ConsumeIntegral<uint64_t>());
102
103 ElfPushFakeFunctionData(data_provider, interface_fake);
104 ElfPushFakeStepData(data_provider);
105
106 elf->FakeSetInterface(interface_fake);
107 ElfInterfaceFake::FakeClear();
108 return elf;
109 }
110
111 static constexpr size_t kPageSize = 4096;
112
AlignToPage(uint64_t address,uint64_t * aligned_address)113 static inline bool AlignToPage(uint64_t address, uint64_t* aligned_address) {
114 if (__builtin_add_overflow(address, kPageSize - 1, aligned_address)) {
115 return false;
116 }
117 *aligned_address &= ~(kPageSize - 1);
118 return true;
119 }
120
GetMaps(FuzzedDataProvider * data_provider)121 std::unique_ptr<Maps> GetMaps(FuzzedDataProvider* data_provider) {
122 std::unique_ptr<Maps> maps = std::make_unique<Maps>();
123 std::map<uint64_t, uint64_t> map_ends;
124 uint8_t entry_count = data_provider->ConsumeIntegralInRange<uint8_t>(0, kMaxMapEntryCount);
125 for (uint8_t i = 0; i < entry_count; i++) {
126 uint64_t start;
127 if (!AlignToPage(data_provider->ConsumeIntegral<uint64_t>(), &start)) {
128 // Overflowed.
129 continue;
130 }
131 uint64_t end;
132 if (!AlignToPage(data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX), &end)) {
133 // Overflowed.
134 continue;
135 }
136 if (start == end) {
137 // It's impossible to see start == end in the real world, so
138 // make sure the map contains at least one page of data.
139 if (__builtin_add_overflow(end, 0x1000, &end)) {
140 continue;
141 }
142 }
143 // Make sure not to add overlapping maps, that is not something that can
144 // happen in the real world.
145 auto entry = map_ends.upper_bound(start);
146 if (entry != map_ends.end() && end > entry->second) {
147 continue;
148 }
149 map_ends[end] = start;
150
151 uint64_t offset;
152 if (!AlignToPage(data_provider->ConsumeIntegral<uint64_t>(), &offset)) {
153 // Overflowed.
154 continue;
155 }
156 std::string map_info_name = data_provider->ConsumeRandomLengthString(kMaxMapInfoNameLen);
157 uint8_t flags = PROT_READ | PROT_WRITE;
158
159 bool exec = data_provider->ConsumeBool();
160 if (exec) {
161 flags |= PROT_EXEC;
162 }
163
164 bool shouldAddElf = data_provider->ConsumeBool();
165 if (shouldAddElf) {
166 ElfAddMapInfo(maps.get(), start, end, offset, flags, map_info_name.c_str(),
167 PopulateElfFake(data_provider));
168 } else {
169 ElfAddMapInfo(maps.get(), start, end, offset, flags, map_info_name.c_str());
170 }
171 }
172 maps->Sort();
173 return maps;
174 }
175
176 // This code (until PutElfFilesInMemory) is pretty much directly copied from JitDebugTest.cpp
177 // There's a few minor modifications, most notably, all methods accept a MemoryFake pointer, and
178 // PutElfInMemory inserts JIT data when called.
WriteDescriptor32(MemoryFake * memory,uint64_t addr,uint32_t entry)179 void WriteDescriptor32(MemoryFake* memory, uint64_t addr, uint32_t entry) {
180 // Format of the 32 bit JITDescriptor structure:
181 // uint32_t version
182 memory->SetData32(addr, 1);
183 // uint32_t action_flag
184 memory->SetData32(addr + 4, 0);
185 // uint32_t relevant_entry
186 memory->SetData32(addr + 8, 0);
187 // uint32_t first_entry
188 memory->SetData32(addr + 12, entry);
189 }
190
WriteDescriptor64(MemoryFake * memory,uint64_t addr,uint64_t entry)191 void WriteDescriptor64(MemoryFake* memory, uint64_t addr, uint64_t entry) {
192 // Format of the 64 bit JITDescriptor structure:
193 // uint32_t version
194 memory->SetData32(addr, 1);
195 // uint32_t action_flag
196 memory->SetData32(addr + 4, 0);
197 // uint64_t relevant_entry
198 memory->SetData64(addr + 8, 0);
199 // uint64_t first_entry
200 memory->SetData64(addr + 16, entry);
201 }
202
WriteEntry32Pack(MemoryFake * memory,uint64_t addr,uint32_t prev,uint32_t next,uint32_t elf_addr,uint64_t elf_size)203 void WriteEntry32Pack(MemoryFake* memory, uint64_t addr, uint32_t prev, uint32_t next,
204 uint32_t elf_addr, uint64_t elf_size) {
205 // Format of the 32 bit JITCodeEntry structure:
206 // uint32_t next
207 memory->SetData32(addr, next);
208 // uint32_t prev
209 memory->SetData32(addr + 4, prev);
210 // uint32_t symfile_addr
211 memory->SetData32(addr + 8, elf_addr);
212 // uint64_t symfile_size
213 memory->SetData64(addr + 12, elf_size);
214 }
215
WriteEntry32Pad(MemoryFake * memory,uint64_t addr,uint32_t prev,uint32_t next,uint32_t elf_addr,uint64_t elf_size)216 void WriteEntry32Pad(MemoryFake* memory, uint64_t addr, uint32_t prev, uint32_t next,
217 uint32_t elf_addr, uint64_t elf_size) {
218 // Format of the 32 bit JITCodeEntry structure:
219 // uint32_t next
220 memory->SetData32(addr, next);
221 // uint32_t prev
222 memory->SetData32(addr + 4, prev);
223 // uint32_t symfile_addr
224 memory->SetData32(addr + 8, elf_addr);
225 // uint32_t pad
226 memory->SetData32(addr + 12, 0);
227 // uint64_t symfile_size
228 memory->SetData64(addr + 16, elf_size);
229 }
230
WriteEntry64(MemoryFake * memory,uint64_t addr,uint64_t prev,uint64_t next,uint64_t elf_addr,uint64_t elf_size)231 void WriteEntry64(MemoryFake* memory, uint64_t addr, uint64_t prev, uint64_t next,
232 uint64_t elf_addr, uint64_t elf_size) {
233 // Format of the 64 bit JITCodeEntry structure:
234 // uint64_t next
235 memory->SetData64(addr, next);
236 // uint64_t prev
237 memory->SetData64(addr + 8, prev);
238 // uint64_t symfile_addr
239 memory->SetData64(addr + 16, elf_addr);
240 // uint64_t symfile_size
241 memory->SetData64(addr + 24, elf_size);
242 }
243
244 template <typename EhdrType, typename ShdrType>
PutElfInMemory(MemoryFake * memory,uint64_t offset,uint8_t class_type,uint8_t machine_type,uint32_t pc,uint32_t size)245 void PutElfInMemory(MemoryFake* memory, uint64_t offset, uint8_t class_type, uint8_t machine_type,
246 uint32_t pc, uint32_t size) {
247 EhdrType ehdr;
248 memset(&ehdr, 0, sizeof(ehdr));
249 uint64_t sh_offset = sizeof(ehdr);
250 memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
251 ehdr.e_ident[EI_CLASS] = class_type;
252 ehdr.e_machine = machine_type;
253 ehdr.e_shstrndx = 1;
254 ehdr.e_shoff = sh_offset;
255 ehdr.e_shentsize = sizeof(ShdrType);
256 ehdr.e_shnum = 3;
257 memory->SetMemory(offset, &ehdr, sizeof(ehdr));
258
259 ShdrType shdr;
260 memset(&shdr, 0, sizeof(shdr));
261 shdr.sh_type = SHT_NULL;
262 memory->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
263
264 sh_offset += sizeof(shdr);
265 memset(&shdr, 0, sizeof(shdr));
266 shdr.sh_type = SHT_STRTAB;
267 shdr.sh_name = 1;
268 shdr.sh_offset = 0x500;
269 shdr.sh_size = 0x100;
270 memory->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
271 memory->SetMemory(offset + 0x500, ".debug_frame");
272
273 sh_offset += sizeof(shdr);
274 memset(&shdr, 0, sizeof(shdr));
275 shdr.sh_type = SHT_PROGBITS;
276 shdr.sh_name = 0;
277 shdr.sh_addr = 0x600;
278 shdr.sh_offset = 0x600;
279 shdr.sh_size = 0x200;
280 memory->SetMemory(offset + sh_offset, &shdr, sizeof(shdr));
281
282 // Now add a single cie/fde.
283 uint64_t dwarf_offset = offset + 0x600;
284 if (class_type == ELFCLASS32) {
285 // CIE 32 information.
286 memory->SetData32(dwarf_offset, 0xfc);
287 memory->SetData32(dwarf_offset + 0x4, 0xffffffff);
288 memory->SetData8(dwarf_offset + 0x8, 1);
289 memory->SetData8(dwarf_offset + 0x9, '\0');
290 memory->SetData8(dwarf_offset + 0xa, 0x4);
291 memory->SetData8(dwarf_offset + 0xb, 0x4);
292 memory->SetData8(dwarf_offset + 0xc, 0x1);
293
294 // FDE 32 information.
295 memory->SetData32(dwarf_offset + 0x100, 0xfc);
296 memory->SetData32(dwarf_offset + 0x104, 0);
297 memory->SetData32(dwarf_offset + 0x108, pc);
298 memory->SetData32(dwarf_offset + 0x10c, size);
299 } else {
300 // CIE 64 information.
301 memory->SetData32(dwarf_offset, 0xffffffff);
302 memory->SetData64(dwarf_offset + 4, 0xf4);
303 memory->SetData64(dwarf_offset + 0xc, 0xffffffffffffffffULL);
304 memory->SetData8(dwarf_offset + 0x14, 1);
305 memory->SetData8(dwarf_offset + 0x15, '\0');
306 memory->SetData8(dwarf_offset + 0x16, 0x4);
307 memory->SetData8(dwarf_offset + 0x17, 0x4);
308 memory->SetData8(dwarf_offset + 0x18, 0x1);
309
310 // FDE 64 information.
311 memory->SetData32(dwarf_offset + 0x100, 0xffffffff);
312 memory->SetData64(dwarf_offset + 0x104, 0xf4);
313 memory->SetData64(dwarf_offset + 0x10c, 0);
314 memory->SetData64(dwarf_offset + 0x114, pc);
315 memory->SetData64(dwarf_offset + 0x11c, size);
316 }
317 }
318
PutElfFilesInMemory(MemoryFake * memory,FuzzedDataProvider * data_provider)319 void PutElfFilesInMemory(MemoryFake* memory, FuzzedDataProvider* data_provider) {
320 uint8_t elf_file_count = data_provider->ConsumeIntegralInRange<uint8_t>(0, kMaxJitElfFiles);
321 int entry_offset = 0;
322 int prev_jit_addr = 0;
323 for (uint8_t i = 0; i < elf_file_count; i++) {
324 uint64_t offset = data_provider->ConsumeIntegral<uint64_t>();
325 // Technically the max valid value is ELFCLASSNUM - 1 (2), but
326 // we want to test values outside of that range.
327 uint8_t class_type = data_provider->ConsumeIntegral<uint8_t>();
328 // Same here, EM_NUM is 253, max valid machine type is 252
329 uint8_t machine_type = data_provider->ConsumeIntegral<uint8_t>();
330 uint32_t pc = data_provider->ConsumeIntegral<uint32_t>();
331 uint32_t size = data_provider->ConsumeIntegral<uint32_t>();
332 bool sixty_four_bit = data_provider->ConsumeBool();
333 bool write_jit = data_provider->ConsumeBool();
334 if (sixty_four_bit) {
335 PutElfInMemory<Elf64_Ehdr, Elf64_Shdr>(memory, offset, class_type, machine_type, pc, size);
336 } else {
337 PutElfInMemory<Elf32_Ehdr, Elf32_Shdr>(memory, offset, class_type, machine_type, pc, size);
338 }
339 if (write_jit) {
340 bool use_pad = data_provider->ConsumeBool();
341 // It is possible this will overwrite part of the ELF.
342 // This provides an interesting test of how malformed ELF
343 // data is handled.
344 uint64_t cur_descriptor_addr = 0x11800 + entry_offset;
345 uint64_t cur_jit_addr = 0x200000 + entry_offset;
346 uint64_t next_jit_addr = cur_jit_addr + size;
347 if (sixty_four_bit) {
348 WriteDescriptor64(memory, 0x11800, cur_jit_addr);
349 WriteEntry64(memory, cur_jit_addr, prev_jit_addr, next_jit_addr, pc, size);
350 } else {
351 // Loop back. Again, this may corrupt data,
352 // but that will allow for testing edge cases with
353 // malformed JIT data.
354 if (cur_jit_addr > UINT32_MAX) {
355 entry_offset = 0;
356 cur_jit_addr = 0x200000;
357 cur_descriptor_addr = 0x11800;
358 next_jit_addr = cur_jit_addr + size;
359 }
360 WriteDescriptor32(memory, cur_descriptor_addr, cur_jit_addr);
361 if (use_pad) {
362 WriteEntry32Pad(memory, cur_jit_addr, prev_jit_addr, next_jit_addr, pc, size);
363 } else {
364 WriteEntry32Pack(memory, cur_jit_addr, prev_jit_addr, next_jit_addr, pc, size);
365 }
366 }
367 entry_offset += size;
368 prev_jit_addr = cur_jit_addr;
369 }
370 }
371 }
372
GetStringList(FuzzedDataProvider * data_provider,uint max_str_len,uint max_strings)373 std::vector<std::string> GetStringList(FuzzedDataProvider* data_provider, uint max_str_len,
374 uint max_strings) {
375 uint str_count = data_provider->ConsumeIntegralInRange<uint>(0, max_strings);
376 std::vector<std::string> strings;
377 for (uint i = 0; i < str_count; i++) {
378 strings.push_back(data_provider->ConsumeRandomLengthString(max_str_len));
379 }
380 return strings;
381 }
382
GetDexFiles(FuzzedDataProvider * data_provider,std::shared_ptr<Memory> memory,uint max_library_length,uint max_libraries,ArchEnum arch)383 std::unique_ptr<DexFiles> GetDexFiles(FuzzedDataProvider* data_provider,
384 std::shared_ptr<Memory> memory, uint max_library_length,
385 uint max_libraries, ArchEnum arch) {
386 std::vector<std::string> search_libs =
387 GetStringList(data_provider, max_library_length, max_libraries);
388 if (search_libs.size() <= 0) {
389 return CreateDexFiles(arch, memory);
390 }
391
392 return CreateDexFiles(arch, memory, search_libs);
393 }
394