[llvm] [llvm-objdump][ELF] Ensure offset to verdaux entry array does not go past size (PR #115284)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 8 09:51:01 PST 2024
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/115284
>From 4aa80da3e5c5b9099fadc4c51160ba0c23aabe1c Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Fri, 8 Nov 2024 18:50:44 +0100
Subject: [PATCH] [llvm-objdump][ELF] Ensure offset to verdaux entry array does
not go past size
Validate `vd_aux` while parsing `Elf_Verdef` structure.
Fixes: https://github.com/llvm/llvm-project/issues/86611.
---
.../llvm-objdump/ELF/invalid-verdef.test | 25 +++++++++++++++++++
llvm/tools/llvm-objdump/ELFDump.cpp | 17 ++++++++++---
2 files changed, 38 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/tools/llvm-objdump/ELF/invalid-verdef.test
diff --git a/llvm/test/tools/llvm-objdump/ELF/invalid-verdef.test b/llvm/test/tools/llvm-objdump/ELF/invalid-verdef.test
new file mode 100644
index 00000000000000..9f6ea6d1c5193e
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/invalid-verdef.test
@@ -0,0 +1,25 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objdump -p %t 2>&1 | FileCheck --check-prefix=BROKEN-VERDEF -DFILE=%t %s
+
+## Ensure we emit a warning when vd_aux offset field is invalid.
+
+# BROKEN-VERDEF: Version definitions:
+# BROKEN-VERDEF-NEXT: warning: '[[FILE]]': corrupted section: vd_aux value 69 in section verdef points past end of the section
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+Sections:
+ - Name: .gnu.version_d
+ Type: SHT_GNU_verdef
+ Entries:
+ - Version: 1
+ Flags: 0
+ VersionNdx: 0
+ VDAux: 69
+ Names:
+ - VERSION_1
+DynamicSymbols: []
+...
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index 5ac13495662faf..bfa5f57d2f0ec7 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -39,6 +39,9 @@ template <typename ELFT> class ELFDumper : public Dumper {
void printProgramHeaders();
void printSymbolVersion();
void printSymbolVersionDependency(const typename ELFT::Shdr &Sec);
+ void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
+ ArrayRef<uint8_t> Contents,
+ StringRef StrTab);
};
} // namespace
@@ -380,9 +383,9 @@ void ELFDumper<ELFT>::printSymbolVersionDependency(
}
template <class ELFT>
-static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
- ArrayRef<uint8_t> Contents,
- StringRef StrTab) {
+void ELFDumper<ELFT>::printSymbolVersionDefinition(
+ const typename ELFT::Shdr &Shdr, ArrayRef<uint8_t> Contents,
+ StringRef StrTab) {
outs() << "\nVersion definitions:\n";
const uint8_t *Buf = Contents.data();
@@ -398,6 +401,12 @@ static void printSymbolVersionDefinition(const typename ELFT::Shdr &Shdr,
<< format("0x%08" PRIx32 " ", (uint32_t)Verdef->vd_hash);
const uint8_t *BufAux = Buf + Verdef->vd_aux;
+ if (BufAux > Contents.end()) {
+ reportWarning("corrupted section: vd_aux value " + Twine(Verdef->vd_aux) +
+ " in section verdef points past end of the section",
+ Obj.getFileName());
+ break;
+ }
uint16_t VerdauxIndex = 0;
while (BufAux) {
auto *Verdaux = reinterpret_cast<const typename ELFT::Verdaux *>(BufAux);
@@ -430,7 +439,7 @@ template <class ELFT> void ELFDumper<ELFT>::printSymbolVersion() {
if (Shdr.sh_type == ELF::SHT_GNU_verneed)
printSymbolVersionDependency(Shdr);
else
- printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab);
+ printSymbolVersionDefinition(Shdr, Contents, StrTab);
}
}
More information about the llvm-commits
mailing list