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