Skip to content

Commit

Permalink
llvm-objdump/ELF: fix crash when reading dyn str table (#87519)
Browse files Browse the repository at this point in the history
When reading the dynamic string table, llvm-objdump used to crash if the
ELF was malformed, due to an erroneous consumption of error status.
Instead, propogate the error status to the caller, fixing the crash, and
printing a warning.
  • Loading branch information
artagnon committed Apr 6, 2024
1 parent d288444 commit 0e8b61f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
28 changes: 26 additions & 2 deletions llvm/test/tools/llvm-objdump/ELF/dynamic-malformed.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .dynamic
Type: SHT_DYNAMIC
Expand All @@ -29,10 +28,35 @@ FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_SONAME
Value: 1

# RUN: yaml2obj %s --docnum=3 -o %t.invalidaddr
# RUN: llvm-objdump -p %t.invalidaddr 2>&1 | \
# RUN: FileCheck %s -DFILE=%t.invalidaddr --implicit-check-not=warning: --check-prefix=ADDR

# ADDR: Dynamic Section:
# ADDR-NEXT: warning: '[[FILE]]': virtual address is not in any segment: 0x474
# ADDR-NEXT: NEEDED 0xffffffffbe5a0b5f
# ADDR-NEXT: STRTAB 0x0000000000000474

---
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Sections:
- Name: .dynamic
Type: SHT_DYNAMIC
Entries:
- Tag: DT_NEEDED
Value: 0xFFFFFFFFBE5A0B5F
- Tag: DT_STRTAB
Value: 0x474
- Tag: DT_NULL
Value: 0x0
11 changes: 6 additions & 5 deletions llvm/tools/llvm-objdump/ELFDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static Expected<StringRef> getDynamicStrTab(const ELFFile<ELFT> &Elf) {
if (Dyn.d_tag == ELF::DT_STRTAB) {
auto MappedAddrOrError = Elf.toMappedAddr(Dyn.getPtr());
if (!MappedAddrOrError)
consumeError(MappedAddrOrError.takeError());
return MappedAddrOrError.takeError();
return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
}
}
Expand Down Expand Up @@ -223,7 +223,6 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
continue;

std::string Str = Elf.getDynamicTagAsString(Dyn.d_tag);
outs() << format(TagFmt.c_str(), Str.c_str());

const char *Fmt =
ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
Expand All @@ -232,14 +231,16 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
if (StrTabOrErr) {
const char *Data = StrTabOrErr.get().data();
outs() << (Data + Dyn.d_un.d_val) << "\n";
const char *Data = StrTabOrErr->data();
outs() << format(TagFmt.c_str(), Str.c_str()) << Data + Dyn.getVal()
<< "\n";
continue;
}
reportWarning(toString(StrTabOrErr.takeError()), Obj.getFileName());
consumeError(StrTabOrErr.takeError());
}
outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
outs() << format(TagFmt.c_str(), Str.c_str())
<< format(Fmt, (uint64_t)Dyn.getVal());
}
}

Expand Down

0 comments on commit 0e8b61f

Please sign in to comment.