Skip to content

Commit ab4c234

Browse files
[llvm-objdump][ELF] Ensure offset to verdaux entry array does not go past size
Validate `vd_aux` while parsing `Elf_Verdef` structure. Fixes: #86611.
1 parent d4ae050 commit ab4c234

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

Diff for: llvm/test/tools/llvm-objdump/ELF/invalid-verdef.test

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: llvm-objdump -p %t 2>&1 | FileCheck --check-prefix=BROKEN-VERDEF -DFILE=%t %s
3+
4+
## Ensure we emit a warning when vd_aux offset field is invalid.
5+
6+
# BROKEN-VERDEF: Version definitions:
7+
# BROKEN-VERDEF-NEXT: warning: '[[FILE]]': corrupted section: vd_aux value 69 in section verdef points past end of the section
8+
9+
--- !ELF
10+
FileHeader:
11+
Class: ELFCLASS64
12+
Data: ELFDATA2LSB
13+
Type: ET_DYN
14+
Sections:
15+
- Name: .gnu.version_d
16+
Type: SHT_GNU_verdef
17+
Entries:
18+
- Version: 1
19+
Flags: 0
20+
VersionNdx: 0
21+
VDAux: 69
22+
Names:
23+
- VERSION_1
24+
DynamicSymbols: []
25+
...

Diff for: llvm/tools/llvm-objdump/ELFDump.cpp

+13-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ template <typename ELFT> class ELFDumper : public Dumper {
3939
void printProgramHeaders();
4040
void printSymbolVersion();
4141
void printSymbolVersionDependency(const typename ELFT::Shdr &Sec);
42+
void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
43+
ArrayRef<uint8_t> Contents,
44+
StringRef StrTab);
4245
};
4346
} // namespace
4447

@@ -380,9 +383,9 @@ void ELFDumper<ELFT>::printSymbolVersionDependency(
380383
}
381384

382385
template <class ELFT>
383-
static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
384-
ArrayRef<uint8_t> Contents,
385-
StringRef StrTab) {
386+
void ELFDumper<ELFT>::printSymbolVersionDefinition(
387+
const typename ELFT::Shdr &Shdr, ArrayRef<uint8_t> Contents,
388+
StringRef StrTab) {
386389
outs() << "\nVersion definitions:\n";
387390

388391
const uint8_t *Buf = Contents.data();
@@ -398,6 +401,12 @@ static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
398401
<< format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
399402

400403
const uint8_t *BufAux = Buf + Verdef->vd_aux;
404+
if (BufAux > Contents.end()) {
405+
reportWarning("corrupted section: vd_aux value " + Twine(Verdef->vd_aux) +
406+
" in section verdef points past end of the section",
407+
Obj.getFileName());
408+
break;
409+
}
401410
uint16_t VerdauxIndex = 0;
402411
while (BufAux) {
403412
auto *Verdaux = reinterpret_cast<const typename ELFT::Verdaux *>(BufAux);
@@ -430,7 +439,7 @@ template <class ELFT> void ELFDumper<ELFT>::printSymbolVersion() {
430439
if (Shdr.sh_type == ELF::SHT_GNU_verneed)
431440
printSymbolVersionDependency(Shdr);
432441
else
433-
printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab);
442+
printSymbolVersionDefinition(Shdr, Contents, StrTab);
434443
}
435444
}
436445

0 commit comments

Comments
 (0)