Skip to content

Commit 2cc5751

Browse files
committed
[llvm-objdump][ELF]Fix crash when reading strings from .dynstr(#86612)
This change introduces a check for the strtab offset to prevent llvm-objdump from crashing when processing malformed ELF files. Additionally, it modifies how llvm-objdump handles and outputs malformed ELF files with invalid string offsets. More info: https://discourse.llvm.org/t/should-llvm-objdump-objdump-display-actual-corrupted-values-in-malformed-elf-files/84391 Signed-off-by: cabbaken <cabbaken@outlook.com>
1 parent c0861e9 commit 2cc5751

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

llvm/test/tools/llvm-objdump/ELF/dynamic-section.test

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ ProgramHeaders:
438438
# RUN: yaml2obj --docnum=4 %s -o %t4
439439
# RUN: llvm-objdump -p %t4 | FileCheck %s --strict-whitespace --check-prefix=INDENT
440440

441+
# RUN: yaml2obj --docnum=5 %s -o %t5
442+
# RUN: llvm-objdump -p %t5 | FileCheck %s --strict-whitespace --check-prefix=INDENT
443+
441444
# INDENT: {{^}}Dynamic Section:
442445
# INDENT: {{^}} NEEDED 0x
443446

@@ -470,3 +473,34 @@ Sections:
470473
Value: 0x1
471474
- Tag: DT_NULL
472475
Value: 0x0
476+
477+
--- !ELF
478+
FileHeader:
479+
Class: ELFCLASS64
480+
Data: ELFDATA2LSB
481+
Type: ET_EXEC
482+
Machine: EM_X86_64
483+
Sections:
484+
- Name: .dynstr
485+
Type: SHT_STRTAB
486+
Address: 0x1000
487+
Size: 0x10
488+
Content: "004400550066007700"
489+
- Name: .dynamic
490+
Type: SHT_DYNAMIC
491+
Entries:
492+
- Tag: DT_NEEDED
493+
Value: 0x1245657656
494+
- Tag: DT_STRTAB
495+
Value: 0x1000
496+
- Tag: DT_NULL
497+
Value: 0x0
498+
ProgramHeaders:
499+
- Type: PT_LOAD
500+
VAddr: 0x1000
501+
FirstSec: .dynstr
502+
LastSec: .dynamic
503+
- Type: PT_DYNAMIC
504+
VAddr: 0x101D
505+
FirstSec: .dynamic
506+
LastSec: .dynamic

llvm/tools/llvm-objdump/ELFDump.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
#include "ELFDump.h"
1515

1616
#include "llvm-objdump.h"
17+
#include "llvm/BinaryFormat/ELF.h"
1718
#include "llvm/Demangle/Demangle.h"
19+
#include "llvm/Object/ELF.h"
1820
#include "llvm/Object/ELFObjectFile.h"
21+
#include "llvm/Object/ELFTypes.h"
1922
#include "llvm/Support/Format.h"
2023
#include "llvm/Support/raw_ostream.h"
2124

@@ -221,6 +224,20 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
221224
std::string TagFmt = " %-" + std::to_string(MaxLen) + "s ";
222225

223226
outs() << "\nDynamic Section:\n";
227+
auto StringTableSize = (typename ELFT::Xword)0;
228+
for (const auto &Sec : cantFail(Elf.sections())) {
229+
if (Sec.sh_type == ELF::SHT_STRTAB)
230+
StringTableSize =
231+
StringTableSize < Sec.sh_size ? Sec.sh_size : StringTableSize;
232+
}
233+
for (const typename ELFT::Dyn &Dyn : DynamicEntries) {
234+
if (Dyn.d_tag == ELF::DT_STRSZ) {
235+
StringTableSize =
236+
StringTableSize < Dyn.getVal() ? Dyn.getVal() : StringTableSize;
237+
break;
238+
}
239+
}
240+
224241
for (const typename ELFT::Dyn &Dyn : DynamicEntries) {
225242
if (Dyn.d_tag == ELF::DT_NULL)
226243
continue;
@@ -235,6 +252,12 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicSection() {
235252
Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
236253
if (StrTabOrErr) {
237254
const char *Data = StrTabOrErr->data();
255+
if (Dyn.getVal() >= StringTableSize) {
256+
reportWarning("invalid string table offset", Obj.getFileName());
257+
outs() << format(TagFmt.c_str(), Str.c_str())
258+
<< format(Fmt, (uint64_t)Dyn.getVal());
259+
continue;
260+
}
238261
outs() << format(TagFmt.c_str(), Str.c_str()) << Data + Dyn.getVal()
239262
<< "\n";
240263
continue;

0 commit comments

Comments
 (0)