Fix off-by-one in ReadBuildIDFromMemory.

This was sometimes causing build ids to be truncated, probably because
of memory corruption in std::string. A similar off-by-one was fixed in
ReadBuildID in aosp/939619.

Bug: 129873279
Change-Id: I401fe7f991dbd135f5b4836381b48ea3c6a2243f
This commit is contained in:
Peter Collingbourne 2020-03-30 18:38:21 -07:00
parent fd193bd291
commit a7b4c5d25a
2 changed files with 12 additions and 7 deletions

View File

@ -662,7 +662,7 @@ std::string ElfInterface::ReadBuildIDFromMemory(Memory* memory) {
if (note_size - offset < hdr.n_descsz || hdr.n_descsz == 0) { if (note_size - offset < hdr.n_descsz || hdr.n_descsz == 0) {
return ""; return "";
} }
std::string build_id(hdr.n_descsz - 1, '\0'); std::string build_id(hdr.n_descsz, '\0');
if (memory->ReadFully(note_offset + offset, &build_id[0], hdr.n_descsz)) { if (memory->ReadFully(note_offset + offset, &build_id[0], hdr.n_descsz)) {
return build_id; return build_id;
} }

View File

@ -142,15 +142,14 @@ static void InitElfData(int fd) {
char note_section[128]; char note_section[128];
Elf32_Nhdr note_header = {}; Elf32_Nhdr note_header = {};
note_header.n_namesz = 4; // "GNU" note_header.n_namesz = sizeof("GNU");
note_header.n_descsz = 12; // "ELF_BUILDID" note_header.n_descsz = sizeof("ELF_BUILDID") - 1;
note_header.n_type = NT_GNU_BUILD_ID; note_header.n_type = NT_GNU_BUILD_ID;
memcpy(&note_section, &note_header, sizeof(note_header)); memcpy(&note_section, &note_header, sizeof(note_header));
size_t note_offset = sizeof(note_header); size_t note_offset = sizeof(note_header);
memcpy(&note_section[note_offset], "GNU", sizeof("GNU")); memcpy(&note_section[note_offset], "GNU", note_header.n_namesz);
note_offset += sizeof("GNU"); note_offset += note_header.n_namesz;
memcpy(&note_section[note_offset], "ELF_BUILDID", sizeof("ELF_BUILDID")); memcpy(&note_section[note_offset], "ELF_BUILDID", note_header.n_descsz);
note_offset += sizeof("ELF_BUILDID");
Elf32_Shdr shdr = {}; Elf32_Shdr shdr = {};
shdr.sh_type = SHT_NOTE; shdr.sh_type = SHT_NOTE;
@ -195,4 +194,10 @@ TEST_F(MapInfoGetBuildIDTest, multiple_thread_elf_exists_in_memory) {
MultipleThreadTest("ELF_BUILDID"); MultipleThreadTest("ELF_BUILDID");
} }
TEST_F(MapInfoGetBuildIDTest, real_elf) {
MapInfo map_info(nullptr, nullptr, 0x1000, 0x20000, 0, PROT_READ | PROT_WRITE,
TestGetFileDirectory() + "offline/empty_arm64/libc.so");
EXPECT_EQ("6df0590c4920f4c7b9f34fe833f37d54", map_info.GetPrintableBuildID());
}
} // namespace unwindstack } // namespace unwindstack