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