[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