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 <memory>
27 #include <vector>
28
29 #include <android-base/file.h>
30 #include <gtest/gtest.h>
31
32 #include <unwindstack/Elf.h>
33 #include <unwindstack/MapInfo.h>
34 #include <unwindstack/Maps.h>
35 #include <unwindstack/Memory.h>
36
37 #include "ElfTestUtils.h"
38 #include "MemoryFake.h"
39
40 namespace unwindstack {
41
42 class MapInfoCreateMemoryTest : public ::testing::Test {
43 protected:
44 template <typename Ehdr, typename Shdr>
InitElf(int fd,uint64_t file_offset,uint64_t sh_offset,uint8_t class_type)45 static void InitElf(int fd, uint64_t file_offset, uint64_t sh_offset, uint8_t class_type) {
46 std::vector<uint8_t> buffer(20000);
47 memset(buffer.data(), 0, buffer.size());
48
49 Ehdr ehdr;
50 memset(&ehdr, 0, sizeof(ehdr));
51 memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
52 ehdr.e_ident[EI_CLASS] = class_type;
53 ehdr.e_shoff = sh_offset;
54 ehdr.e_shentsize = sizeof(Shdr) + 100;
55 ehdr.e_shnum = 4;
56 memcpy(&buffer[file_offset], &ehdr, sizeof(ehdr));
57
58 ASSERT_TRUE(android::base::WriteFully(fd, buffer.data(), buffer.size()));
59 }
60
SetUpTestCase()61 static void SetUpTestCase() {
62 std::vector<uint8_t> buffer(12288, 0);
63 memcpy(buffer.data(), ELFMAG, SELFMAG);
64 buffer[EI_CLASS] = ELFCLASS32;
65 ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), 1024));
66
67 memset(buffer.data(), 0, buffer.size());
68 memcpy(&buffer[0x1000], ELFMAG, SELFMAG);
69 buffer[0x1000 + EI_CLASS] = ELFCLASS64;
70 buffer[0x2000] = 0xff;
71 ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, buffer.data(), buffer.size()));
72
73 InitElf<Elf32_Ehdr, Elf32_Shdr>(elf32_at_map_.fd, 0x1000, 0x2000, ELFCLASS32);
74 InitElf<Elf64_Ehdr, Elf64_Shdr>(elf64_at_map_.fd, 0x2000, 0x3000, ELFCLASS64);
75 }
76
SetUp()77 void SetUp() override {
78 memory_ = new MemoryFake;
79 process_memory_.reset(memory_);
80 }
81
82 MemoryFake* memory_;
83 std::shared_ptr<Memory> process_memory_;
84
85 static TemporaryFile elf_;
86
87 static TemporaryFile elf_at_1000_;
88
89 static TemporaryFile elf32_at_map_;
90 static TemporaryFile elf64_at_map_;
91 };
92 TemporaryFile MapInfoCreateMemoryTest::elf_;
93 TemporaryFile MapInfoCreateMemoryTest::elf_at_1000_;
94 TemporaryFile MapInfoCreateMemoryTest::elf32_at_map_;
95 TemporaryFile MapInfoCreateMemoryTest::elf64_at_map_;
96
TEST_F(MapInfoCreateMemoryTest,end_le_start)97 TEST_F(MapInfoCreateMemoryTest, end_le_start) {
98 MapInfo info(nullptr, 0x100, 0x100, 0, 0, elf_.path);
99
100 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
101 ASSERT_TRUE(memory.get() == nullptr);
102
103 info.end = 0xff;
104 memory.reset(info.CreateMemory(process_memory_));
105 ASSERT_TRUE(memory.get() == nullptr);
106
107 // Make sure this test is valid.
108 info.end = 0x101;
109 memory.reset(info.CreateMemory(process_memory_));
110 ASSERT_TRUE(memory.get() != nullptr);
111 EXPECT_FALSE(info.memory_backed_elf);
112 }
113
114 // Verify that if the offset is non-zero but there is no elf at the offset,
115 // that the full file is used.
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_full_file)116 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) {
117 MapInfo info(nullptr, 0x100, 0x200, 0x100, 0, elf_.path);
118
119 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
120 ASSERT_TRUE(memory.get() != nullptr);
121 EXPECT_FALSE(info.memory_backed_elf);
122 ASSERT_EQ(0x100U, info.elf_offset);
123 EXPECT_EQ(0x100U, info.elf_start_offset);
124
125 // Read the entire file.
126 std::vector<uint8_t> buffer(1024);
127 ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 1024));
128 ASSERT_TRUE(memcmp(buffer.data(), ELFMAG, SELFMAG) == 0);
129 ASSERT_EQ(ELFCLASS32, buffer[EI_CLASS]);
130 for (size_t i = EI_CLASS + 1; i < buffer.size(); i++) {
131 ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
132 }
133
134 ASSERT_FALSE(memory->ReadFully(1024, buffer.data(), 1));
135
136 // Now verify the elf start offset is set correctly based on the previous
137 // info.
138 MapInfo prev_info(nullptr, 0, 0x100, 0x10, 0, "");
139 info.prev_map = &prev_info;
140
141 // No preconditions met, change each one until it should set the elf start
142 // offset to zero.
143 info.elf_offset = 0;
144 info.elf_start_offset = 0;
145 info.memory_backed_elf = false;
146 memory.reset(info.CreateMemory(process_memory_));
147 ASSERT_TRUE(memory.get() != nullptr);
148 EXPECT_FALSE(info.memory_backed_elf);
149 ASSERT_EQ(0x100U, info.elf_offset);
150 EXPECT_EQ(0x100U, info.elf_start_offset);
151
152 prev_info.offset = 0;
153 info.elf_offset = 0;
154 info.elf_start_offset = 0;
155 info.memory_backed_elf = false;
156 memory.reset(info.CreateMemory(process_memory_));
157 ASSERT_TRUE(memory.get() != nullptr);
158 EXPECT_FALSE(info.memory_backed_elf);
159 ASSERT_EQ(0x100U, info.elf_offset);
160 EXPECT_EQ(0x100U, info.elf_start_offset);
161
162 prev_info.flags = PROT_READ;
163 info.elf_offset = 0;
164 info.elf_start_offset = 0;
165 info.memory_backed_elf = false;
166 memory.reset(info.CreateMemory(process_memory_));
167 ASSERT_TRUE(memory.get() != nullptr);
168 EXPECT_FALSE(info.memory_backed_elf);
169 ASSERT_EQ(0x100U, info.elf_offset);
170 EXPECT_EQ(0x100U, info.elf_start_offset);
171
172 prev_info.name = info.name;
173 info.elf_offset = 0;
174 info.elf_start_offset = 0;
175 info.memory_backed_elf = false;
176 memory.reset(info.CreateMemory(process_memory_));
177 ASSERT_TRUE(memory.get() != nullptr);
178 EXPECT_FALSE(info.memory_backed_elf);
179 ASSERT_EQ(0x100U, info.elf_offset);
180 EXPECT_EQ(0U, info.elf_start_offset);
181 }
182
183 // Verify that if the offset is non-zero and there is an elf at that
184 // offset, that only part of the file is used.
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_partial_file)185 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) {
186 MapInfo info(nullptr, 0x100, 0x200, 0x1000, 0, elf_at_1000_.path);
187
188 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
189 ASSERT_TRUE(memory.get() != nullptr);
190 EXPECT_FALSE(info.memory_backed_elf);
191 ASSERT_EQ(0U, info.elf_offset);
192 EXPECT_EQ(0x1000U, info.elf_start_offset);
193
194 // Read the valid part of the file.
195 std::vector<uint8_t> buffer(0x100);
196 ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100));
197 ASSERT_TRUE(memcmp(buffer.data(), ELFMAG, SELFMAG) == 0);
198 ASSERT_EQ(ELFCLASS64, buffer[EI_CLASS]);
199 for (size_t i = EI_CLASS + 1; i < buffer.size(); i++) {
200 ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
201 }
202
203 ASSERT_FALSE(memory->ReadFully(0x100, buffer.data(), 1));
204 }
205
206 // Verify that if the offset is non-zero and there is an elf at that
207 // offset, that only part of the file is used. Further verify that if the
208 // embedded elf is bigger than the initial map, the new object is larger
209 // than the original map size. Do this for a 32 bit elf and a 64 bit elf.
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_partial_file_whole_elf32)210 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf32) {
211 MapInfo info(nullptr, 0x5000, 0x6000, 0x1000, 0, elf32_at_map_.path);
212
213 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
214 ASSERT_TRUE(memory.get() != nullptr);
215 EXPECT_FALSE(info.memory_backed_elf);
216 ASSERT_EQ(0U, info.elf_offset);
217 EXPECT_EQ(0x1000U, info.elf_start_offset);
218
219 // Verify the memory is a valid elf.
220 uint8_t e_ident[SELFMAG + 1];
221 ASSERT_TRUE(memory->ReadFully(0, e_ident, SELFMAG));
222 ASSERT_EQ(0, memcmp(e_ident, ELFMAG, SELFMAG));
223
224 // Read past the end of what would normally be the size of the map.
225 ASSERT_TRUE(memory->ReadFully(0x1000, e_ident, 1));
226 }
227
TEST_F(MapInfoCreateMemoryTest,file_backed_non_zero_offset_partial_file_whole_elf64)228 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf64) {
229 MapInfo info(nullptr, 0x7000, 0x8000, 0x2000, 0, elf64_at_map_.path);
230
231 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
232 ASSERT_TRUE(memory.get() != nullptr);
233 EXPECT_FALSE(info.memory_backed_elf);
234 ASSERT_EQ(0U, info.elf_offset);
235 EXPECT_EQ(0x2000U, info.elf_start_offset);
236
237 // Verify the memory is a valid elf.
238 uint8_t e_ident[SELFMAG + 1];
239 ASSERT_TRUE(memory->ReadFully(0, e_ident, SELFMAG));
240 ASSERT_EQ(0, memcmp(e_ident, ELFMAG, SELFMAG));
241
242 // Read past the end of what would normally be the size of the map.
243 ASSERT_TRUE(memory->ReadFully(0x1000, e_ident, 1));
244 }
245
246 // Verify that device file names will never result in Memory object creation.
TEST_F(MapInfoCreateMemoryTest,check_device_maps)247 TEST_F(MapInfoCreateMemoryTest, check_device_maps) {
248 // Set up some memory so that a valid local memory object would
249 // be returned if the file mapping fails, but the device check is incorrect.
250 std::vector<uint8_t> buffer(1024);
251 uint64_t start = reinterpret_cast<uint64_t>(buffer.data());
252 MapInfo info(nullptr, start, start + buffer.size(), 0, 0x8000, "/dev/something");
253
254 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
255 ASSERT_TRUE(memory.get() == nullptr);
256 }
257
TEST_F(MapInfoCreateMemoryTest,process_memory)258 TEST_F(MapInfoCreateMemoryTest, process_memory) {
259 MapInfo info(nullptr, 0x2000, 0x3000, 0, PROT_READ, "");
260
261 Elf32_Ehdr ehdr = {};
262 TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
263 std::vector<uint8_t> buffer(1024);
264 memcpy(buffer.data(), &ehdr, sizeof(ehdr));
265
266 // Verify that the the process_memory object is used, so seed it
267 // with memory.
268 for (size_t i = sizeof(ehdr); i < buffer.size(); i++) {
269 buffer[i] = i % 256;
270 }
271 memory_->SetMemory(info.start, buffer.data(), buffer.size());
272
273 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
274 ASSERT_TRUE(memory.get() != nullptr);
275 EXPECT_TRUE(info.memory_backed_elf);
276
277 memset(buffer.data(), 0, buffer.size());
278 ASSERT_TRUE(memory->ReadFully(0, buffer.data(), buffer.size()));
279 ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
280 for (size_t i = sizeof(ehdr); i < buffer.size(); i++) {
281 ASSERT_EQ(i % 256, buffer[i]) << "Failed at byte " << i;
282 }
283
284 // Try to read outside of the map size.
285 ASSERT_FALSE(memory->ReadFully(buffer.size(), buffer.data(), 1));
286 }
287
TEST_F(MapInfoCreateMemoryTest,valid_rosegment_zero_offset)288 TEST_F(MapInfoCreateMemoryTest, valid_rosegment_zero_offset) {
289 Maps maps;
290 maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
291 maps.Add(0x1000, 0x2600, 0, PROT_READ, "/only/in/memory.so", 0);
292 maps.Add(0x3000, 0x5000, 0x4000, PROT_READ | PROT_EXEC, "/only/in/memory.so", 0);
293
294 Elf32_Ehdr ehdr = {};
295 TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
296 memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr));
297 memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x1600 - sizeof(ehdr), 0xab);
298
299 // Set the memory in the r-x map.
300 memory_->SetMemoryBlock(0x3000, 0x2000, 0x5d);
301
302 MapInfo* map_info = maps.Find(0x3000);
303 ASSERT_TRUE(map_info != nullptr);
304
305 std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
306 ASSERT_TRUE(mem.get() != nullptr);
307 EXPECT_TRUE(map_info->memory_backed_elf);
308 EXPECT_EQ(0x4000UL, map_info->elf_offset);
309 EXPECT_EQ(0x4000UL, map_info->offset);
310 EXPECT_EQ(0U, map_info->elf_start_offset);
311
312 // Verify that reading values from this memory works properly.
313 std::vector<uint8_t> buffer(0x4000);
314 size_t bytes = mem->Read(0, buffer.data(), buffer.size());
315 ASSERT_EQ(0x1600UL, bytes);
316 ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
317 for (size_t i = sizeof(ehdr); i < bytes; i++) {
318 ASSERT_EQ(0xab, buffer[i]) << "Failed at byte " << i;
319 }
320
321 bytes = mem->Read(0x4000, buffer.data(), buffer.size());
322 ASSERT_EQ(0x2000UL, bytes);
323 for (size_t i = 0; i < bytes; i++) {
324 ASSERT_EQ(0x5d, buffer[i]) << "Failed at byte " << i;
325 }
326 }
327
TEST_F(MapInfoCreateMemoryTest,valid_rosegment_non_zero_offset)328 TEST_F(MapInfoCreateMemoryTest, valid_rosegment_non_zero_offset) {
329 Maps maps;
330 maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
331 maps.Add(0x1000, 0x2000, 0, PROT_READ, "/only/in/memory.apk", 0);
332 maps.Add(0x2000, 0x3000, 0x1000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0);
333 maps.Add(0x3000, 0x4000, 0xa000, PROT_READ, "/only/in/memory.apk", 0);
334 maps.Add(0x4000, 0x5000, 0xb000, PROT_READ | PROT_EXEC, "/only/in/memory.apk", 0);
335
336 Elf32_Ehdr ehdr = {};
337 TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
338
339 // Setup an elf at offset 0x1000 in memory.
340 memory_->SetMemory(0x1000, &ehdr, sizeof(ehdr));
341 memory_->SetMemoryBlock(0x1000 + sizeof(ehdr), 0x2000 - sizeof(ehdr), 0x12);
342 memory_->SetMemoryBlock(0x2000, 0x1000, 0x23);
343
344 // Setup an elf at offset 0x3000 in memory..
345 memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
346 memory_->SetMemoryBlock(0x3000 + sizeof(ehdr), 0x4000 - sizeof(ehdr), 0x34);
347 memory_->SetMemoryBlock(0x4000, 0x1000, 0x43);
348
349 MapInfo* map_info = maps.Find(0x4000);
350 ASSERT_TRUE(map_info != nullptr);
351
352 std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
353 ASSERT_TRUE(mem.get() != nullptr);
354 EXPECT_TRUE(map_info->memory_backed_elf);
355 EXPECT_EQ(0x1000UL, map_info->elf_offset);
356 EXPECT_EQ(0xb000UL, map_info->offset);
357 EXPECT_EQ(0xa000UL, map_info->elf_start_offset);
358
359 // Verify that reading values from this memory works properly.
360 std::vector<uint8_t> buffer(0x4000);
361 size_t bytes = mem->Read(0, buffer.data(), buffer.size());
362 ASSERT_EQ(0x1000UL, bytes);
363 ASSERT_EQ(0, memcmp(&ehdr, buffer.data(), sizeof(ehdr)));
364 for (size_t i = sizeof(ehdr); i < bytes; i++) {
365 ASSERT_EQ(0x34, buffer[i]) << "Failed at byte " << i;
366 }
367
368 bytes = mem->Read(0x1000, buffer.data(), buffer.size());
369 ASSERT_EQ(0x1000UL, bytes);
370 for (size_t i = 0; i < bytes; i++) {
371 ASSERT_EQ(0x43, buffer[i]) << "Failed at byte " << i;
372 }
373 }
374
TEST_F(MapInfoCreateMemoryTest,rosegment_from_file)375 TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) {
376 Maps maps;
377 maps.Add(0x500, 0x600, 0, PROT_READ, "something_else", 0);
378 maps.Add(0x1000, 0x2000, 0x1000, PROT_READ, elf_at_1000_.path, 0);
379 maps.Add(0x2000, 0x3000, 0x2000, PROT_READ | PROT_EXEC, elf_at_1000_.path, 0);
380
381 MapInfo* map_info = maps.Find(0x2000);
382 ASSERT_TRUE(map_info != nullptr);
383
384 // Set up the size
385 Elf64_Ehdr ehdr;
386 ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
387 ASSERT_TRUE(android::base::ReadFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
388
389 // Will not give the elf memory, because the read-only entry does not
390 // extend over the executable segment.
391 std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_));
392 ASSERT_TRUE(memory.get() != nullptr);
393 EXPECT_FALSE(map_info->memory_backed_elf);
394 std::vector<uint8_t> buffer(0x100);
395 EXPECT_EQ(0x2000U, map_info->offset);
396 EXPECT_EQ(0U, map_info->elf_offset);
397 EXPECT_EQ(0U, map_info->elf_start_offset);
398 ASSERT_TRUE(memory->ReadFully(0, buffer.data(), 0x100));
399 EXPECT_EQ(0xffU, buffer[0]);
400
401 // Now init the elf data enough so that the file memory object will be used.
402 ehdr.e_shoff = 0x4000;
403 ehdr.e_shnum = 1;
404 ehdr.e_shentsize = 0x100;
405 ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
406 ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
407
408 map_info->memory_backed_elf = false;
409 memory.reset(map_info->CreateMemory(process_memory_));
410 EXPECT_FALSE(map_info->memory_backed_elf);
411 EXPECT_EQ(0x2000U, map_info->offset);
412 EXPECT_EQ(0x1000U, map_info->elf_offset);
413 EXPECT_EQ(0x1000U, map_info->elf_start_offset);
414 Elf64_Ehdr ehdr_mem;
415 ASSERT_TRUE(memory->ReadFully(0, &ehdr_mem, sizeof(ehdr_mem)));
416 EXPECT_TRUE(memcmp(&ehdr, &ehdr_mem, sizeof(ehdr)) == 0);
417 }
418
419 } // namespace unwindstack
420