1 /*
2  * Copyright (C) 2016 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 <elf.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include <string.h>
21 #include <sys/mman.h>
22 #include <sys/ptrace.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include <atomic>
27 #include <memory>
28 #include <thread>
29 #include <vector>
30 
31 #include <android-base/file.h>
32 #include <android-base/test_utils.h>
33 #include <gtest/gtest.h>
34 
35 #include <unwindstack/Elf.h>
36 #include <unwindstack/MapInfo.h>
37 #include <unwindstack/Maps.h>
38 #include <unwindstack/Memory.h>
39 
40 #include "ElfTestUtils.h"
41 #include "MemoryFake.h"
42 
43 namespace unwindstack {
44 
45 class MapInfoGetElfTest : public ::testing::Test {
46  protected:
47   void SetUp() override {
48     memory_ = new MemoryFake;
49     process_memory_.reset(memory_);
50   }
51 
52   template <typename Ehdr, typename Shdr>
53   static void InitElf(uint64_t sh_offset, Ehdr* ehdr, uint8_t class_type, uint8_t machine_type) {
54     memset(ehdr, 0, sizeof(*ehdr));
55     memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
56     ehdr->e_ident[EI_CLASS] = class_type;
57     ehdr->e_machine = machine_type;
58     ehdr->e_shoff = sh_offset;
59     ehdr->e_shentsize = sizeof(Shdr) + 100;
60     ehdr->e_shnum = 4;
61   }
62 
63   const size_t kMapSize = 4096;
64 
65   std::shared_ptr<Memory> process_memory_;
66   MemoryFake* memory_;
67 
68   TemporaryFile elf_;
69 };
70 
71 TEST_F(MapInfoGetElfTest, invalid) {
72   MapInfo info(0x1000, 0x2000, 0, PROT_READ, "");
73 
74   // The map is empty, but this should still create an invalid elf object.
75   Elf* elf = info.GetElf(process_memory_, false);
76   ASSERT_TRUE(elf != nullptr);
77   ASSERT_FALSE(elf->valid());
78 }
79 
80 TEST_F(MapInfoGetElfTest, valid32) {
81   MapInfo info(0x3000, 0x4000, 0, PROT_READ, "");
82 
83   Elf32_Ehdr ehdr;
84   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
85   memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
86 
87   Elf* elf = info.GetElf(process_memory_, false);
88   ASSERT_TRUE(elf != nullptr);
89   ASSERT_TRUE(elf->valid());
90   EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
91   EXPECT_EQ(ELFCLASS32, elf->class_type());
92 }
93 
94 TEST_F(MapInfoGetElfTest, valid64) {
95   MapInfo info(0x8000, 0x9000, 0, PROT_READ, "");
96 
97   Elf64_Ehdr ehdr;
98   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
99   memory_->SetMemory(0x8000, &ehdr, sizeof(ehdr));
100 
101   Elf* elf = info.GetElf(process_memory_, false);
102   ASSERT_TRUE(elf != nullptr);
103   ASSERT_TRUE(elf->valid());
104   EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
105   EXPECT_EQ(ELFCLASS64, elf->class_type());
106 }
107 
108 TEST_F(MapInfoGetElfTest, gnu_debugdata_do_not_init32) {
109   MapInfo info(0x4000, 0x8000, 0, PROT_READ, "");
110 
111   TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, false,
112                                                [&](uint64_t offset, const void* ptr, size_t size) {
113                                                  memory_->SetMemory(0x4000 + offset, ptr, size);
114                                                });
115 
116   Elf* elf = info.GetElf(process_memory_, false);
117   ASSERT_TRUE(elf != nullptr);
118   ASSERT_TRUE(elf->valid());
119   EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
120   EXPECT_EQ(ELFCLASS32, elf->class_type());
121   EXPECT_TRUE(elf->gnu_debugdata_interface() == nullptr);
122 }
123 
124 TEST_F(MapInfoGetElfTest, gnu_debugdata_do_not_init64) {
125   MapInfo info(0x6000, 0x8000, 0, PROT_READ, "");
126 
127   TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, false,
128                                                [&](uint64_t offset, const void* ptr, size_t size) {
129                                                  memory_->SetMemory(0x6000 + offset, ptr, size);
130                                                });
131 
132   Elf* elf = info.GetElf(process_memory_, false);
133   ASSERT_TRUE(elf != nullptr);
134   ASSERT_TRUE(elf->valid());
135   EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
136   EXPECT_EQ(ELFCLASS64, elf->class_type());
137   EXPECT_TRUE(elf->gnu_debugdata_interface() == nullptr);
138 }
139 
140 TEST_F(MapInfoGetElfTest, gnu_debugdata_init32) {
141   MapInfo info(0x2000, 0x3000, 0, PROT_READ, "");
142 
143   TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true,
144                                                [&](uint64_t offset, const void* ptr, size_t size) {
145                                                  memory_->SetMemory(0x2000 + offset, ptr, size);
146                                                });
147 
148   Elf* elf = info.GetElf(process_memory_, true);
149   ASSERT_TRUE(elf != nullptr);
150   ASSERT_TRUE(elf->valid());
151   EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
152   EXPECT_EQ(ELFCLASS32, elf->class_type());
153   EXPECT_TRUE(elf->gnu_debugdata_interface() != nullptr);
154 }
155 
156 TEST_F(MapInfoGetElfTest, gnu_debugdata_init64) {
157   MapInfo info(0x5000, 0x8000, 0, PROT_READ, "");
158 
159   TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true,
160                                                [&](uint64_t offset, const void* ptr, size_t size) {
161                                                  memory_->SetMemory(0x5000 + offset, ptr, size);
162                                                });
163 
164   Elf* elf = info.GetElf(process_memory_, true);
165   ASSERT_TRUE(elf != nullptr);
166   ASSERT_TRUE(elf->valid());
167   EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
168   EXPECT_EQ(ELFCLASS64, elf->class_type());
169   EXPECT_TRUE(elf->gnu_debugdata_interface() != nullptr);
170 }
171 
172 TEST_F(MapInfoGetElfTest, end_le_start) {
173   MapInfo info(0x1000, 0x1000, 0, PROT_READ, elf_.path);
174 
175   Elf32_Ehdr ehdr;
176   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
177   ASSERT_TRUE(android::base::WriteFully(elf_.fd, &ehdr, sizeof(ehdr)));
178 
179   Elf* elf = info.GetElf(process_memory_, false);
180   ASSERT_TRUE(elf != nullptr);
181   ASSERT_FALSE(elf->valid());
182 
183   info.elf.reset();
184   info.end = 0xfff;
185   elf = info.GetElf(process_memory_, false);
186   ASSERT_TRUE(elf != nullptr);
187   ASSERT_FALSE(elf->valid());
188 
189   // Make sure this test is valid.
190   info.elf.reset();
191   info.end = 0x2000;
192   elf = info.GetElf(process_memory_, false);
193   ASSERT_TRUE(elf != nullptr);
194   ASSERT_TRUE(elf->valid());
195 }
196 
197 // Verify that if the offset is non-zero but there is no elf at the offset,
198 // that the full file is used.
199 TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_full_file) {
200   MapInfo info(0x1000, 0x2000, 0x100, PROT_READ, elf_.path);
201 
202   std::vector<uint8_t> buffer(0x1000);
203   memset(buffer.data(), 0, buffer.size());
204   Elf32_Ehdr ehdr;
205   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
206   memcpy(buffer.data(), &ehdr, sizeof(ehdr));
207   ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
208 
209   Elf* elf = info.GetElf(process_memory_, false);
210   ASSERT_TRUE(elf != nullptr);
211   ASSERT_TRUE(elf->valid());
212   ASSERT_TRUE(elf->memory() != nullptr);
213   ASSERT_EQ(0x100U, info.elf_offset);
214 
215   // Read the entire file.
216   memset(buffer.data(), 0, buffer.size());
217   ASSERT_TRUE(elf->memory()->ReadFully(0, buffer.data(), buffer.size()));
218   ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
219   for (size_t i = sizeof(ehdr); i < buffer.size(); i++) {
220     ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
221   }
222 
223   ASSERT_FALSE(elf->memory()->ReadFully(buffer.size(), buffer.data(), 1));
224 }
225 
226 // Verify that if the offset is non-zero and there is an elf at that
227 // offset, that only part of the file is used.
228 TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_partial_file) {
229   MapInfo info(0x1000, 0x2000, 0x2000, PROT_READ, elf_.path);
230 
231   std::vector<uint8_t> buffer(0x4000);
232   memset(buffer.data(), 0, buffer.size());
233   Elf32_Ehdr ehdr;
234   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
235   memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
236   ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
237 
238   Elf* elf = info.GetElf(process_memory_, false);
239   ASSERT_TRUE(elf != nullptr);
240   ASSERT_TRUE(elf->valid());
241   ASSERT_TRUE(elf->memory() != nullptr);
242   ASSERT_EQ(0U, info.elf_offset);
243 
244   // Read the valid part of the file.
245   ASSERT_TRUE(elf->memory()->ReadFully(0, buffer.data(), 0x1000));
246   ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
247   for (size_t i = sizeof(ehdr); i < 0x1000; i++) {
248     ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
249   }
250 
251   ASSERT_FALSE(elf->memory()->ReadFully(0x1000, buffer.data(), 1));
252 }
253 
254 // Verify that if the offset is non-zero and there is an elf at that
255 // offset, that only part of the file is used. Further verify that if the
256 // embedded elf is bigger than the initial map, the new object is larger
257 // than the original map size. Do this for a 32 bit elf and a 64 bit elf.
258 TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_partial_file_whole_elf32) {
259   MapInfo info(0x5000, 0x6000, 0x1000, PROT_READ, elf_.path);
260 
261   std::vector<uint8_t> buffer(0x4000);
262   memset(buffer.data(), 0, buffer.size());
263   Elf32_Ehdr ehdr;
264   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
265   ehdr.e_shoff = 0x2000;
266   ehdr.e_shentsize = sizeof(Elf32_Shdr) + 100;
267   ehdr.e_shnum = 4;
268   memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
269   ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
270 
271   Elf* elf = info.GetElf(process_memory_, false);
272   ASSERT_TRUE(elf != nullptr);
273   ASSERT_TRUE(elf->valid());
274   ASSERT_TRUE(elf->memory() != nullptr);
275   ASSERT_EQ(0U, info.elf_offset);
276 
277   // Verify the memory is a valid elf.
278   memset(buffer.data(), 0, buffer.size());
279   ASSERT_TRUE(elf->memory()->ReadFully(0, buffer.data(), 0x1000));
280   ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
281 
282   // Read past the end of what would normally be the size of the map.
283   ASSERT_TRUE(elf->memory()->ReadFully(0x1000, buffer.data(), 1));
284 }
285 
286 TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_partial_file_whole_elf64) {
287   MapInfo info(0x7000, 0x8000, 0x1000, PROT_READ, elf_.path);
288 
289   std::vector<uint8_t> buffer(0x4000);
290   memset(buffer.data(), 0, buffer.size());
291   Elf64_Ehdr ehdr;
292   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
293   ehdr.e_shoff = 0x2000;
294   ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
295   ehdr.e_shnum = 4;
296   memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
297   ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
298 
299   Elf* elf = info.GetElf(process_memory_, false);
300   ASSERT_TRUE(elf != nullptr);
301   ASSERT_TRUE(elf->valid());
302   ASSERT_TRUE(elf->memory() != nullptr);
303   ASSERT_EQ(0U, info.elf_offset);
304 
305   // Verify the memory is a valid elf.
306   memset(buffer.data(), 0, buffer.size());
307   ASSERT_TRUE(elf->memory()->ReadFully(0, buffer.data(), 0x1000));
308   ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
309 
310   // Read past the end of what would normally be the size of the map.
311   ASSERT_TRUE(elf->memory()->ReadFully(0x1000, buffer.data(), 1));
312 }
313 
314 TEST_F(MapInfoGetElfTest, process_memory_not_read_only) {
315   MapInfo info(0x9000, 0xa000, 0x1000, 0, "");
316 
317   // Create valid elf data in process memory only.
318   Elf64_Ehdr ehdr;
319   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
320   ehdr.e_shoff = 0x2000;
321   ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
322   ehdr.e_shnum = 4;
323   memory_->SetMemory(0x9000, &ehdr, sizeof(ehdr));
324 
325   Elf* elf = info.GetElf(process_memory_, false);
326   ASSERT_TRUE(elf != nullptr);
327   ASSERT_FALSE(elf->valid());
328 
329   info.elf.reset();
330   info.flags = PROT_READ;
331   elf = info.GetElf(process_memory_, false);
332   ASSERT_TRUE(elf->valid());
333 }
334 
335 TEST_F(MapInfoGetElfTest, check_device_maps) {
336   MapInfo info(0x7000, 0x8000, 0x1000, PROT_READ | MAPS_FLAGS_DEVICE_MAP, "/dev/something");
337 
338   // Create valid elf data in process memory for this to verify that only
339   // the name is causing invalid elf data.
340   Elf64_Ehdr ehdr;
341   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_X86_64);
342   ehdr.e_shoff = 0x2000;
343   ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
344   ehdr.e_shnum = 4;
345   memory_->SetMemory(0x7000, &ehdr, sizeof(ehdr));
346 
347   Elf* elf = info.GetElf(process_memory_, false);
348   ASSERT_TRUE(elf != nullptr);
349   ASSERT_FALSE(elf->valid());
350 
351   // Set the name to nothing to verify that it still fails.
352   info.elf.reset();
353   info.name = "";
354   elf = info.GetElf(process_memory_, false);
355   ASSERT_FALSE(elf->valid());
356 
357   // Change the flags and verify the elf is valid now.
358   info.elf.reset();
359   info.flags = PROT_READ;
360   elf = info.GetElf(process_memory_, false);
361   ASSERT_TRUE(elf->valid());
362 }
363 
364 TEST_F(MapInfoGetElfTest, multiple_thread_get_elf) {
365   static constexpr size_t kNumConcurrentThreads = 100;
366 
367   Elf64_Ehdr ehdr;
368   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_X86_64);
369   ehdr.e_shoff = 0x2000;
370   ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
371   ehdr.e_shnum = 4;
372   memory_->SetMemory(0x7000, &ehdr, sizeof(ehdr));
373 
374   Elf* elf_in_threads[kNumConcurrentThreads];
375   std::vector<std::thread*> threads;
376 
377   std::atomic_bool wait;
378   wait = true;
379   // Create all of the threads and have them do the GetElf at the same time
380   // to make it likely that a race will occur.
381   MapInfo info(0x7000, 0x8000, 0x1000, PROT_READ, "");
382   for (size_t i = 0; i < kNumConcurrentThreads; i++) {
383     std::thread* thread = new std::thread([i, this, &wait, &info, &elf_in_threads]() {
384       while (wait)
385         ;
386       Elf* elf = info.GetElf(process_memory_, false);
387       elf_in_threads[i] = elf;
388     });
389     threads.push_back(thread);
390   }
391   ASSERT_TRUE(info.elf == nullptr);
392 
393   // Set them all going and wait for the threads to finish.
394   wait = false;
395   for (auto thread : threads) {
396     thread->join();
397     delete thread;
398   }
399 
400   // Now verify that all of the elf files are exactly the same and valid.
401   Elf* elf = info.elf.get();
402   ASSERT_TRUE(elf != nullptr);
403   EXPECT_TRUE(elf->valid());
404   for (size_t i = 0; i < kNumConcurrentThreads; i++) {
405     EXPECT_EQ(elf, elf_in_threads[i]) << "Thread " << i << " mismatched.";
406   }
407 }
408 
409 }  // namespace unwindstack
410