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