// Tests that the default constructed instance does not report support // for Armv8.5-A BTI.
TEST(note_gnu_property, default) {
GnuPropertySection note;
test_bti_not_supported(note);
ASSERT_NO_ERROR_MSG();
}
// Tests that an instance without valid phdr pointer does not report // support for Armv8.5-A BTI.
TEST(note_gnu_property, phdr_null) { auto note = GnuPropertySection(nullptr, 0, 0, SONAME);
test_bti_not_supported(note);
ASSERT_NO_ERROR_MSG();
}
// Tests that an instance without finding PT_GNU_PROPERTY does not // report support for Armv8.5-A BTI.
TEST(note_gnu_property, no_pt_gnu_property) {
ElfW(Phdr) phdrs[] = {
{.p_type = PT_LOAD},
{.p_type = PT_NULL},
};
reset_error_buffer(); auto note = GnuPropertySection(&phdrs[0], std::size(phdrs), 0, SONAME);
test_bti_not_supported(note);
ASSERT_ERROR_MSG_EQ("PT_GNU_PROPERTY segment is too small. Segment size is 15, minimum is 16.");
}
// Tests that advertised n_descsz should still fit into p_memsz.
TEST(note_gnu_property, pt_gnu_property_too_small) {
ElfW(NhdrGNUProperty) prop = {
.nhdr = {.n_namesz = PT_GNU_PROPERTY, .n_descsz = 1, .n_type = NT_GNU_PROPERTY_TYPE_0},
.n_name = "GNU",
};
ElfW(Phdr) phdrs[] = {
{
.p_type = PT_GNU_PROPERTY,
.p_vaddr = reinterpret_cast<ElfW(Addr)>(&prop),
.p_memsz = sizeof(ElfW(NhdrGNUProperty)), // Off by one
},
};
reset_error_buffer(); auto note = GnuPropertySection(&phdrs[0], std::size(phdrs), 0, SONAME);
test_bti_not_supported(note);
ASSERT_ERROR_MSG_EQ("PT_GNU_PROPERTY segment p_memsz (16) is too small for note n_descsz (1).");
}
// Tests the validity check for not enough space for a Program Property header.
TEST(note_gnu_property, pt_gnu_property_pphdr_no_space) {
ElfW(NhdrGNUProperty) prop = {
.nhdr = {.n_namesz = 4,
.n_descsz = 7, // Invalid
.n_type = NT_GNU_PROPERTY_TYPE_0},
.n_name = "GNU",
};
PHDR_WITH_NOTE_GNU_PROPERTY(&prop);
test_bti_not_supported(note);
ASSERT_ERROR_MSG_EQ(".note.gnu.property: no more space left for a Program Property Note header.");
}
// Tests a .note.gnu.property section with elements with pr_datasz = 0.
TEST(note_gnu_property, pt_gnu_property_no_prop) {
GnuPropertySectionBuilder prop;
ASSERT_TRUE(prop.push(1, 0, (void*)nullptr));
ASSERT_TRUE(prop.push(2, 0, (void*)nullptr));
ASSERT_TRUE(prop.push(3, 0, (void*)nullptr));
PHDR_WITH_NOTE_GNU_PROPERTY(prop.data());
test_bti_not_supported(note);
ASSERT_NO_ERROR_MSG();
}
// Tests that GNU_PROPERTY_AARCH64_FEATURE_1_AND must have pr_datasz = 4.
TEST(note_gnu_property, pt_gnu_property_bad_pr_datasz) { #ifdefined(__aarch64__)
GnuPropertySectionBuilder prop;
ElfW(Word) pr_data[] = {GNU_PROPERTY_AARCH64_FEATURE_1_BTI, 0, 0};
ASSERT_TRUE(prop.push(GNU_PROPERTY_AARCH64_FEATURE_1_AND, 12, &pr_data));
PHDR_WITH_NOTE_GNU_PROPERTY(prop.data());
test_bti_not_supported(note);
ASSERT_ERROR_MSG_EQ( ".note.gnu.property: property descriptor size is invalid. Expected 4 bytes for " "GNU_PROPERTY_AARCH64_FEATURE_1_AND, got 12."); #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
// Tests a .note.gnu.property section with only GNU_PROPERTY_AARCH64_FEATURE_1_BTI property array.
TEST(note_gnu_property, pt_gnu_property_ok_1) { #ifdefined(__aarch64__)
GnuPropertySectionBuilder prop;
ElfW(Word) pr_data[] = {GNU_PROPERTY_AARCH64_FEATURE_1_BTI};
ASSERT_TRUE(prop.push(GNU_PROPERTY_AARCH64_FEATURE_1_AND, sizeof(pr_data), &pr_data));
PHDR_WITH_NOTE_GNU_PROPERTY(prop.data());
ASSERT_NO_ERROR_MSG();
test_bti_supported(note); #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
// Tests a .note.gnu.property section with only GNU_PROPERTY_AARCH64_FEATURE_1_BTI property array.
TEST(note_gnu_property, pt_gnu_property_ok_2) { #ifdefined(__aarch64__)
GnuPropertySectionBuilder prop;
ElfW(Word) pr_data[] = {static_cast<ElfW(Word)>(~GNU_PROPERTY_AARCH64_FEATURE_1_BTI)};
ASSERT_TRUE(prop.push(GNU_PROPERTY_AARCH64_FEATURE_1_AND, sizeof(pr_data), &pr_data));
PHDR_WITH_NOTE_GNU_PROPERTY(prop.data());
ASSERT_NO_ERROR_MSG();
test_bti_not_supported(note); #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
// Tests a .note.gnu.property section with more property arrays.
TEST(note_gnu_property, pt_gnu_property_ok_3) { #ifdefined(__aarch64__)
GnuPropertySectionBuilder prop;
PHDR_WITH_NOTE_GNU_PROPERTY(prop.data());
ASSERT_NO_ERROR_MSG();
test_bti_supported(note); #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
// Tests a .note.gnu.property but with bad property descriptor size.
TEST(note_gnu_property, pt_gnu_property_bad_n_descsz) { #ifdefined(__aarch64__)
GnuPropertySectionBuilder prop;
ElfW(Word) pr_data[] = {GNU_PROPERTY_AARCH64_FEATURE_1_BTI};
ASSERT_TRUE(prop.push(GNU_PROPERTY_AARCH64_FEATURE_1_AND, sizeof(pr_data), &pr_data));
PHDR_WITH_NOTE_GNU_PROPERTY(prop.data()); if (sizeof(ElfW(Addr)) == 4) {
ASSERT_ERROR_MSG_EQ( ".note.gnu.property: property descriptor size is invalid. Expected at least 12 bytes, got " "11.");
} else {
ASSERT_ERROR_MSG_EQ( ".note.gnu.property: property descriptor size is invalid. Expected at least 16 bytes, got " "15.");
}
test_bti_not_supported(note); #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
// Tests if platform support is missing.
TEST(note_gnu_property, no_platform_support) { #ifdefined(__aarch64__) auto bti_supported_orig = g_platform_properties.bti_supported;
g_platform_properties.bti_supported = false;
g_platform_properties.bti_supported = bti_supported_orig; #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
// Test that .note.gnu.property is properly loaded from a binary with a non-zero image base.
TEST(note_gnu_property, find_gnu_property_offset_image_base) { #ifdefined(__aarch64__)
std::string path = GetExecutableDirectory() + "/note_gnu_property.so";
unique_fd fd{TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC))};
ASSERT_GE(fd.get(), 0) << "Failed to open " << path << ": " << strerror(errno);
struct stat file_stat;
ASSERT_NE(TEMP_FAILURE_RETRY(fstat(fd.get(), &file_stat)), -1)
<< "Failed to stat " << path << ": " << strerror(errno);
// Load the binary as if BTI isn't supported so that we can run on any CPU. auto bti_supported_orig = g_platform_properties.bti_supported;
g_platform_properties.bti_supported = false;
address_space_params address_space;
EXPECT_TRUE(elf_reader.Load(&address_space)) << "Failed to load ELF file";
// IsBTICompatible() checks for g_platform_properties.bti_supported.
g_platform_properties.bti_supported = true;
EXPECT_TRUE(elf_reader.note_gnu_property()->IsBTICompatible()) << "Binary is not BTI-compatible";
g_platform_properties.bti_supported = bti_supported_orig; #else
GTEST_SKIP() << "BTI is not supported on this architecture."; #endif
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.