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