Verify that the elf matches the expected arch.
To avoid a case where a malicious app might try and trick the system to
create an elf and register object that mismatches, always verify that they
are the same arch.
Test: Ran unit tests.
Change-Id: I66978e9e02f8e4f396856912e7019528ead4838e
diff --git a/libunwindstack/tests/DexFilesTest.cpp b/libunwindstack/tests/DexFilesTest.cpp
index 3ac3ca6..1ea9e5c 100644
--- a/libunwindstack/tests/DexFilesTest.cpp
+++ b/libunwindstack/tests/DexFilesTest.cpp
@@ -36,12 +36,20 @@
class DexFilesTest : public ::testing::Test {
protected:
- void SetUp() override {
- memory_ = new MemoryFake;
- process_memory_.reset(memory_);
+ void CreateFakeElf(MapInfo* map_info) {
+ MemoryFake* memory = new MemoryFake;
+ ElfFake* elf = new ElfFake(memory);
+ elf->FakeSetValid(true);
+ ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
+ elf->FakeSetInterface(interface);
+ interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
+ map_info->elf.reset(elf);
+ }
+
+ void Init(ArchEnum arch) {
dex_files_.reset(new DexFiles(process_memory_));
- dex_files_->SetArch(ARCH_ARM);
+ dex_files_->SetArch(arch);
maps_.reset(
new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf\n"
@@ -58,35 +66,24 @@
// Global variable in a section that is not readable.
MapInfo* map_info = maps_->Get(kMapGlobalNonReadable);
ASSERT_TRUE(map_info != nullptr);
- MemoryFake* memory = new MemoryFake;
- ElfFake* elf = new ElfFake(memory);
- elf->FakeSetValid(true);
- ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
- elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
- map_info->elf.reset(elf);
+ CreateFakeElf(map_info);
// Global variable not set by default.
map_info = maps_->Get(kMapGlobalSetToZero);
ASSERT_TRUE(map_info != nullptr);
- memory = new MemoryFake;
- elf = new ElfFake(memory);
- elf->FakeSetValid(true);
- interface = new ElfInterfaceFake(memory);
- elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
- map_info->elf.reset(elf);
+ CreateFakeElf(map_info);
// Global variable set in this map.
map_info = maps_->Get(kMapGlobal);
ASSERT_TRUE(map_info != nullptr);
- memory = new MemoryFake;
- elf = new ElfFake(memory);
- elf->FakeSetValid(true);
- interface = new ElfInterfaceFake(memory);
- elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
- map_info->elf.reset(elf);
+ CreateFakeElf(map_info);
+ }
+
+ void SetUp() override {
+ memory_ = new MemoryFake;
+ process_memory_.reset(memory_);
+
+ Init(ARCH_ARM);
}
void WriteDescriptor32(uint64_t addr, uint32_t head);
@@ -169,11 +166,12 @@
}
TEST_F(DexFilesTest, get_method_information_64) {
+ Init(ARCH_ARM64);
+
std::string method_name = "nothing";
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- dex_files_->SetArch(ARCH_ARM64);
WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0, 0, 0x301000);
WriteDex(0x301000);
@@ -199,11 +197,12 @@
}
TEST_F(DexFilesTest, get_method_information_not_first_entry_64) {
+ Init(ARCH_ARM64);
+
std::string method_name = "nothing";
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
- dex_files_->SetArch(ARCH_ARM64);
WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0x200100, 0, 0x100000);
WriteEntry64(0x200100, 0, 0x200000, 0x300000);
@@ -297,6 +296,8 @@
}
TEST_F(DexFilesTest, get_method_information_global_skip_zero_64) {
+ Init(ARCH_ARM64);
+
std::string method_name = "nothing";
uint64_t method_offset = 0x124;
MapInfo* info = maps_->Get(kMapDexFiles);
@@ -308,7 +309,6 @@
WriteEntry64(0x200000, 0, 0, 0x300000);
WriteDex(0x300000);
- dex_files_->SetArch(ARCH_ARM64);
dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
EXPECT_EQ("Main.<init>", method_name);
EXPECT_EQ(0U, method_offset);
diff --git a/libunwindstack/tests/ElfCacheTest.cpp b/libunwindstack/tests/ElfCacheTest.cpp
index 8ed697c..d9acdec 100644
--- a/libunwindstack/tests/ElfCacheTest.cpp
+++ b/libunwindstack/tests/ElfCacheTest.cpp
@@ -82,9 +82,9 @@
MapInfo info1(nullptr, start, end, 0, 0x5, tf.path);
MapInfo info2(nullptr, start, end, 0, 0x5, tf.path);
- Elf* elf1 = info1.GetElf(memory_);
+ Elf* elf1 = info1.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf1->valid());
- Elf* elf2 = info2.GetElf(memory_);
+ Elf* elf2 = info2.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf2->valid());
if (cache_enabled) {
@@ -132,10 +132,10 @@
MapInfo info300_1(nullptr, start, end, 0x300, 0x5, tf.path);
MapInfo info300_2(nullptr, start, end, 0x300, 0x5, tf.path);
- Elf* elf0_1 = info0_1.GetElf(memory_);
+ Elf* elf0_1 = info0_1.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf0_1->valid());
EXPECT_EQ(ARCH_ARM, elf0_1->arch());
- Elf* elf0_2 = info0_2.GetElf(memory_);
+ Elf* elf0_2 = info0_2.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf0_2->valid());
EXPECT_EQ(ARCH_ARM, elf0_2->arch());
EXPECT_EQ(0U, info0_1.elf_offset);
@@ -146,10 +146,10 @@
EXPECT_NE(elf0_1, elf0_2);
}
- Elf* elf100_1 = info100_1.GetElf(memory_);
+ Elf* elf100_1 = info100_1.GetElf(memory_, ARCH_X86);
ASSERT_TRUE(elf100_1->valid());
EXPECT_EQ(ARCH_X86, elf100_1->arch());
- Elf* elf100_2 = info100_2.GetElf(memory_);
+ Elf* elf100_2 = info100_2.GetElf(memory_, ARCH_X86);
ASSERT_TRUE(elf100_2->valid());
EXPECT_EQ(ARCH_X86, elf100_2->arch());
EXPECT_EQ(0U, info100_1.elf_offset);
@@ -160,10 +160,10 @@
EXPECT_NE(elf100_1, elf100_2);
}
- Elf* elf200_1 = info200_1.GetElf(memory_);
+ Elf* elf200_1 = info200_1.GetElf(memory_, ARCH_X86_64);
ASSERT_TRUE(elf200_1->valid());
EXPECT_EQ(ARCH_X86_64, elf200_1->arch());
- Elf* elf200_2 = info200_2.GetElf(memory_);
+ Elf* elf200_2 = info200_2.GetElf(memory_, ARCH_X86_64);
ASSERT_TRUE(elf200_2->valid());
EXPECT_EQ(ARCH_X86_64, elf200_2->arch());
EXPECT_EQ(0U, info200_1.elf_offset);
@@ -174,10 +174,10 @@
EXPECT_NE(elf200_1, elf200_2);
}
- Elf* elf300_1 = info300_1.GetElf(memory_);
+ Elf* elf300_1 = info300_1.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf300_1->valid());
EXPECT_EQ(ARCH_ARM, elf300_1->arch());
- Elf* elf300_2 = info300_2.GetElf(memory_);
+ Elf* elf300_2 = info300_2.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf300_2->valid());
EXPECT_EQ(ARCH_ARM, elf300_2->arch());
EXPECT_EQ(0x300U, info300_1.elf_offset);
@@ -222,10 +222,10 @@
MapInfo info400_1(nullptr, start, end, 0x400, 0x5, tf.path);
MapInfo info400_2(nullptr, start, end, 0x400, 0x5, tf.path);
- Elf* elf300_1 = info300_1.GetElf(memory_);
+ Elf* elf300_1 = info300_1.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf300_1->valid());
EXPECT_EQ(ARCH_ARM, elf300_1->arch());
- Elf* elf300_2 = info300_2.GetElf(memory_);
+ Elf* elf300_2 = info300_2.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf300_2->valid());
EXPECT_EQ(ARCH_ARM, elf300_2->arch());
EXPECT_EQ(0x300U, info300_1.elf_offset);
@@ -236,10 +236,10 @@
EXPECT_NE(elf300_1, elf300_2);
}
- Elf* elf400_1 = info400_1.GetElf(memory_);
+ Elf* elf400_1 = info400_1.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf400_1->valid());
EXPECT_EQ(ARCH_ARM, elf400_1->arch());
- Elf* elf400_2 = info400_2.GetElf(memory_);
+ Elf* elf400_2 = info400_2.GetElf(memory_, ARCH_ARM);
ASSERT_TRUE(elf400_2->valid());
EXPECT_EQ(ARCH_ARM, elf400_2->arch());
EXPECT_EQ(0x400U, info400_1.elf_offset);
diff --git a/libunwindstack/tests/JitDebugTest.cpp b/libunwindstack/tests/JitDebugTest.cpp
index 4598526..b1ca111 100644
--- a/libunwindstack/tests/JitDebugTest.cpp
+++ b/libunwindstack/tests/JitDebugTest.cpp
@@ -35,12 +35,19 @@
class JitDebugTest : public ::testing::Test {
protected:
- void SetUp() override {
- memory_ = new MemoryFake;
- process_memory_.reset(memory_);
+ void CreateFakeElf(MapInfo* map_info) {
+ MemoryFake* memory = new MemoryFake;
+ ElfFake* elf = new ElfFake(memory);
+ elf->FakeSetValid(true);
+ ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
+ elf->FakeSetInterface(interface);
+ interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
+ map_info->elf.reset(elf);
+ }
+ void Init(ArchEnum arch) {
jit_debug_.reset(new JitDebug(process_memory_));
- jit_debug_->SetArch(ARCH_ARM);
+ jit_debug_->SetArch(arch);
maps_.reset(
new BufferMaps("1000-4000 ---s 00000000 00:00 0 /fake/elf1\n"
@@ -57,33 +64,22 @@
MapInfo* map_info = maps_->Get(3);
ASSERT_TRUE(map_info != nullptr);
- MemoryFake* memory = new MemoryFake;
- ElfFake* elf = new ElfFake(memory);
- elf->FakeSetValid(true);
- ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
- elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
- map_info->elf.reset(elf);
+ CreateFakeElf(map_info);
map_info = maps_->Get(5);
ASSERT_TRUE(map_info != nullptr);
- memory = new MemoryFake;
- elf = new ElfFake(memory);
- elf->FakeSetValid(true);
- interface = new ElfInterfaceFake(memory);
- elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
- map_info->elf.reset(elf);
+ CreateFakeElf(map_info);
map_info = maps_->Get(7);
ASSERT_TRUE(map_info != nullptr);
- memory = new MemoryFake;
- elf = new ElfFake(memory);
- elf->FakeSetValid(true);
- interface = new ElfInterfaceFake(memory);
- elf->FakeSetInterface(interface);
- interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800);
- map_info->elf.reset(elf);
+ CreateFakeElf(map_info);
+ }
+
+ void SetUp() override {
+ memory_ = new MemoryFake;
+ process_memory_.reset(memory_);
+
+ Init(ARCH_ARM);
}
template <typename EhdrType, typename ShdrType>
@@ -326,6 +322,8 @@
}
TEST_F(JitDebugTest, get_elf_x86) {
+ Init(ARCH_X86);
+
CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200);
WriteDescriptor32(0xf800, 0x200000);
@@ -343,12 +341,13 @@
}
TEST_F(JitDebugTest, get_elf_64) {
+ Init(ARCH_ARM64);
+
CreateElf<Elf64_Ehdr, Elf64_Shdr>(0x4000, ELFCLASS64, EM_AARCH64, 0x1500, 0x200);
WriteDescriptor64(0xf800, 0x200000);
WriteEntry64(0x200000, 0, 0, 0x4000, 0x1000);
- jit_debug_->SetArch(ARCH_ARM64);
Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500);
ASSERT_TRUE(elf != nullptr);
diff --git a/libunwindstack/tests/MapInfoGetElfTest.cpp b/libunwindstack/tests/MapInfoGetElfTest.cpp
index c6c1c34..4d74696 100644
--- a/libunwindstack/tests/MapInfoGetElfTest.cpp
+++ b/libunwindstack/tests/MapInfoGetElfTest.cpp
@@ -72,7 +72,7 @@
MapInfo info(nullptr, 0x1000, 0x2000, 0, PROT_READ, "");
// The map is empty, but this should still create an invalid elf object.
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_FALSE(elf->valid());
}
@@ -84,7 +84,7 @@
TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
@@ -98,13 +98,25 @@
TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
memory_->SetMemory(0x8000, &ehdr, sizeof(ehdr));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM64);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
EXPECT_EQ(ELFCLASS64, elf->class_type());
}
+TEST_F(MapInfoGetElfTest, invalid_arch_mismatch) {
+ MapInfo info(nullptr, 0x3000, 0x4000, 0, PROT_READ, "");
+
+ Elf32_Ehdr ehdr;
+ TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
+ memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
+
+ Elf* elf = info.GetElf(process_memory_, ARCH_X86);
+ ASSERT_TRUE(elf != nullptr);
+ ASSERT_FALSE(elf->valid());
+}
+
TEST_F(MapInfoGetElfTest, gnu_debugdata_init32) {
MapInfo info(nullptr, 0x2000, 0x3000, 0, PROT_READ, "");
@@ -113,7 +125,7 @@
memory_->SetMemory(0x2000 + offset, ptr, size);
});
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
@@ -129,7 +141,7 @@
memory_->SetMemory(0x5000 + offset, ptr, size);
});
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM64);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
@@ -144,20 +156,20 @@
TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
ASSERT_TRUE(android::base::WriteFully(elf_.fd, &ehdr, sizeof(ehdr)));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_FALSE(elf->valid());
info.elf.reset();
info.end = 0xfff;
- elf = info.GetElf(process_memory_);
+ elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_FALSE(elf->valid());
// Make sure this test is valid.
info.elf.reset();
info.end = 0x2000;
- elf = info.GetElf(process_memory_);
+ elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
}
@@ -174,7 +186,7 @@
memcpy(buffer.data(), &ehdr, sizeof(ehdr));
ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
ASSERT_TRUE(elf->memory() != nullptr);
@@ -203,7 +215,7 @@
memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
ASSERT_TRUE(elf->memory() != nullptr);
@@ -236,7 +248,7 @@
memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
ASSERT_TRUE(elf->memory() != nullptr);
@@ -264,7 +276,7 @@
memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM64);
ASSERT_TRUE(elf != nullptr);
ASSERT_TRUE(elf->valid());
ASSERT_TRUE(elf->memory() != nullptr);
@@ -290,13 +302,13 @@
ehdr.e_shnum = 0;
memory_->SetMemory(0x9000, &ehdr, sizeof(ehdr));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_ARM64);
ASSERT_TRUE(elf != nullptr);
ASSERT_FALSE(elf->valid());
info.elf.reset();
info.flags = PROT_READ;
- elf = info.GetElf(process_memory_);
+ elf = info.GetElf(process_memory_, ARCH_ARM64);
ASSERT_TRUE(elf->valid());
}
@@ -313,20 +325,20 @@
ehdr.e_shnum = 0;
memory_->SetMemory(0x7000, &ehdr, sizeof(ehdr));
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_X86_64);
ASSERT_TRUE(elf != nullptr);
ASSERT_FALSE(elf->valid());
// Set the name to nothing to verify that it still fails.
info.elf.reset();
info.name = "";
- elf = info.GetElf(process_memory_);
+ elf = info.GetElf(process_memory_, ARCH_X86_64);
ASSERT_FALSE(elf->valid());
// Change the flags and verify the elf is valid now.
info.elf.reset();
info.flags = PROT_READ;
- elf = info.GetElf(process_memory_);
+ elf = info.GetElf(process_memory_, ARCH_X86_64);
ASSERT_TRUE(elf->valid());
}
@@ -352,7 +364,7 @@
std::thread* thread = new std::thread([i, this, &wait, &info, &elf_in_threads]() {
while (wait)
;
- Elf* elf = info.GetElf(process_memory_);
+ Elf* elf = info.GetElf(process_memory_, ARCH_X86_64);
elf_in_threads[i] = elf;
});
threads.push_back(thread);