[llvm] r363374 - [llvm-readobj] Don't abort printing of dynamic table if string reference is invalid

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 14 05:02:01 PDT 2019


Author: jhenderson
Date: Fri Jun 14 05:02:01 2019
New Revision: 363374

URL: http://llvm.org/viewvc/llvm-project?rev=363374&view=rev
Log:
[llvm-readobj] Don't abort printing of dynamic table if string reference is invalid

If dynamic table is missing, output "dynamic strtab not found'. If the index is
out of range, output "Invalid Offset<..>".

https://bugs.llvm.org/show_bug.cgi?id=40807

Reviewed by: jhenderson, grimar, MaskRay

Differential Revision: https://reviews.llvm.org/D63084

Patch by Yuanfang Chen.

Removed:
    llvm/trunk/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64
Modified:
    llvm/trunk/test/Object/corrupt.test
    llvm/trunk/test/tools/llvm-readobj/elf-dynamic-malformed.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Removed: llvm/trunk/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64?rev=363373&view=auto
==============================================================================
Binary files llvm/trunk/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64 (original) and llvm/trunk/test/Object/Inputs/corrupt-invalid-strtab.elf.x86-64 (removed) differ

Modified: llvm/trunk/test/Object/corrupt.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/corrupt.test?rev=363374&r1=363373&r2=363374&view=diff
==============================================================================
--- llvm/trunk/test/Object/corrupt.test (original)
+++ llvm/trunk/test/Object/corrupt.test Fri Jun 14 05:02:01 2019
@@ -25,13 +25,6 @@ RUN:     2>&1 | FileCheck --check-prefix
 
 VER: error: Invalid version entry
 
-
-// The file is missing the dynamic string table but has references to it.
-RUN: not llvm-readobj --dynamic-table %p/Inputs/corrupt-invalid-strtab.elf.x86-64 \
-RUN:     2>&1 | FileCheck --check-prefix=STRTAB %s
-
-STRTAB: Invalid dynamic string table reference
-
 RUN: not llvm-readobj -l \
 RUN:   %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \
 RUN:   FileCheck --check-prefix=PHENTSIZE %s

Modified: llvm/trunk/test/tools/llvm-readobj/elf-dynamic-malformed.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-dynamic-malformed.test?rev=363374&r1=363373&r2=363374&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-dynamic-malformed.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/elf-dynamic-malformed.test Fri Jun 14 05:02:01 2019
@@ -68,13 +68,28 @@ ProgramHeaders:
     Sections:
       - Section: .dynamic
 
-# Test handling of string references pointing past the end of the dynamic string table. In this case,
-# we have a DT_NEEDED tag pointing at offset 1 in a 1-byte string table.
+# Test handling of string references pointing past the end of the dynamic string table.
 # RUN: yaml2obj %s --docnum=3 -o %t.bad-string
-# RUN: not llvm-readobj --dynamic-table %t.bad-string 2>&1 | FileCheck %s --check-prefix BAD-STRING
-# RUN: not llvm-readelf --dynamic-table %t.bad-string 2>&1 | FileCheck %s --check-prefix BAD-STRING
+# RUN: llvm-readobj --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-LLVM
+# RUN: llvm-readelf --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-GNU
 
-# BAD-STRING: Invalid dynamic string table reference
+# BAD-STRING-LLVM: 0x000000000000000A STRSZ         1 (bytes)
+# BAD-STRING-LLVM: 0x0000000000000001 NEEDED        Shared library: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000007FFFFFFF FILTER        Filter library: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000007FFFFFFD AUXILIARY     Auxiliary library: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000007FFFFFFE USED          Not needed object: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000000000000E SONAME        Library soname: <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000000000000F RPATH         <Invalid offset 0x1>
+# BAD-STRING-LLVM: 0x000000000000001D RUNPATH       <Invalid offset 0x1>
+
+# BAD-STRING-GNU:  0x000000000000000a (STRSZ)       1 (bytes)
+# BAD-STRING-GNU:  0x0000000000000001 (NEEDED)      Shared library: <Invalid offset 0x1>
+# BAD-STRING-GNU:  0x000000007fffffff (FILTER)      Filter library: <Invalid offset 0x1>
+# BAD-STRING-GNU:  0x000000007ffffffd (AUXILIARY)   Auxiliary library: <Invalid offset 0x1>
+# BAD-STRING-GNU:  0x000000007ffffffe (USED)        Not needed object: <Invalid offset 0x1>
+# BAD-STRING-GNU:  0x000000000000000e (SONAME)      Library soname: <Invalid offset 0x1>
+# BAD-STRING-GNU:  0x000000000000000f (RPATH)       <Invalid offset 0x1>
+# BAD-STRING-GNU:  0x000000000000001d (RUNPATH)     <Invalid offset 0x1>
 
 --- !ELF
 FileHeader:
@@ -96,6 +111,18 @@ Sections:
         Value: 1
       - Tag:   DT_NEEDED
         Value: 1
+      - Tag:   DT_FILTER
+        Value: 1
+      - Tag:   DT_AUXILIARY
+        Value: 1
+      - Tag:   DT_USED
+        Value: 1
+      - Tag:   DT_SONAME
+        Value: 1
+      - Tag:   DT_RPATH
+        Value: 1
+      - Tag:   DT_RUNPATH
+        Value: 1
       - Tag:   DT_NULL
         Value: 0
 ProgramHeaders:
@@ -111,11 +138,19 @@ ProgramHeaders:
 
 # Test handling of DT_STRTAB pointing outside the file's address space.
 # RUN: yaml2obj %s --docnum=4 -o %t.bad-strtab
-# RUN: not llvm-readobj --dynamic-table %t.bad-strtab 2>&1 | FileCheck %s --check-prefix BAD-STRTAB
-# RUN: not llvm-readelf --dynamic-table %t.bad-strtab 2>&1 | FileCheck %s --check-prefix BAD-STRTAB
 
-# BAD-STRTAB: warning: Unable to parse DT_STRTAB: Virtual address is not in any segment
-# BAD-STRTAB: error: Invalid dynamic string table reference
+# RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck %s --check-prefix BAD-STRTAB-ERR
+# RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck %s --check-prefix BAD-STRTAB-ERR
+# BAD-STRTAB-ERR: warning: Unable to parse DT_STRTAB: Virtual address is not in any segment
+
+# RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-LLVM
+# RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-GNU
+# BAD-STRTAB-LLVM: LoadName: <Not found>
+# BAD-STRTAB-LLVM: 0x0000000000000001  NEEDED   Shared library: <String table is empty or was not found>
+# BAD-STRTAB-GNU:  0x0000000000000001 (NEEDED)  Shared library: <String table is empty or was not found>
+# BAD-STRTAB:      NeededLibraries [
+# BAD-STRTAB:        <Library name index out of range>
+# BAD-STRTAB:      ]
 
 --- !ELF
 FileHeader:

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=363374&r1=363373&r2=363374&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Fri Jun 14 05:02:01 2019
@@ -206,7 +206,8 @@ private:
   void loadDynamicTable(const ELFFile<ELFT> *Obj);
   void parseDynamicTable();
 
-  StringRef getDynamicString(uint64_t Offset) const;
+  void printDynamicString(uint64_t Offset, raw_ostream &OS,
+                          bool WithBracket = true) const;
   StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
                              bool &IsDefault) const;
   void LoadVersionMap() const;
@@ -221,7 +222,7 @@ private:
   DynRegionInfo DynSymRegion;
   DynRegionInfo DynamicTable;
   StringRef DynamicStringTable;
-  StringRef SOName;
+  StringRef SOName = "<Not found>";
   const Elf_Hash *HashTable = nullptr;
   const Elf_GnuHash *GnuHashTable = nullptr;
   const Elf_Shdr *DotSymtabSec = nullptr;
@@ -1626,8 +1627,8 @@ template <typename ELFT> void ELFDumper<
   }
   if (StringTableBegin)
     DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
-  if (SONameOffset)
-    SOName = getDynamicString(SONameOffset);
+  if (SONameOffset && SONameOffset < DynamicStringTable.size())
+    SOName = DynamicStringTable.data() + SONameOffset;
 }
 
 template <typename ELFT>
@@ -1790,14 +1791,19 @@ void printFlags(T Value, ArrayRef<EnumEn
 }
 
 template <class ELFT>
-StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
-  if (Value >= DynamicStringTable.size())
-    reportError("Invalid dynamic string table reference");
-  return StringRef(DynamicStringTable.data() + Value);
-}
-
-static void printLibrary(raw_ostream &OS, const Twine &Tag, const Twine &Name) {
-  OS << Tag << ": [" << Name << "]";
+void ELFDumper<ELFT>::printDynamicString(uint64_t Value,
+                                         raw_ostream &OS,
+                                         bool WithBracket) const {
+  if (DynamicStringTable.empty())
+    OS << "<String table is empty or was not found> ";
+  else if (Value < DynamicStringTable.size()) {
+    if (WithBracket)
+      OS << "[";
+    OS << StringRef(DynamicStringTable.data() + Value);
+    if (WithBracket)
+      OS << "]";
+  } else
+    OS << "<Invalid offset 0x" << utohexstr(Value) << ">";
 }
 
 template <class ELFT>
@@ -1943,23 +1949,24 @@ void ELFDumper<ELFT>::printDynamicEntry(
     OS << Value << " (bytes)";
     break;
   case DT_NEEDED:
-    printLibrary(OS, "Shared library", getDynamicString(Value));
-    break;
   case DT_SONAME:
-    printLibrary(OS, "Library soname", getDynamicString(Value));
-    break;
   case DT_AUXILIARY:
-    printLibrary(OS, "Auxiliary library", getDynamicString(Value));
-    break;
   case DT_USED:
-    printLibrary(OS, "Not needed object", getDynamicString(Value));
-    break;
-  case DT_FILTER:
-    printLibrary(OS, "Filter library", getDynamicString(Value));
+  case DT_FILTER: {
+    const std::map<uint64_t, const char*> TagNames = {
+      {DT_NEEDED,    "Shared library"},
+      {DT_SONAME,    "Library soname"},
+      {DT_AUXILIARY, "Auxiliary library"},
+      {DT_USED,      "Not needed object"},
+      {DT_FILTER,    "Filter library"},
+    };
+    OS << TagNames.at(Type) << ": ";
+    printDynamicString(Value, OS);
     break;
+  }
   case DT_RPATH:
   case DT_RUNPATH:
-    OS << getDynamicString(Value);
+    printDynamicString(Value, OS, false);
     break;
   case DT_FLAGS:
     printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
@@ -2004,8 +2011,13 @@ template <class ELFT> void ELFDumper<ELF
   LibsTy Libs;
 
   for (const auto &Entry : dynamic_table())
-    if (Entry.d_tag == ELF::DT_NEEDED)
-      Libs.push_back(getDynamicString(Entry.d_un.d_val));
+    if (Entry.d_tag == ELF::DT_NEEDED) {
+      uint64_t Value = Entry.d_un.d_val;
+      if (Value < DynamicStringTable.size())
+        Libs.push_back(StringRef(DynamicStringTable.data() + Value));
+      else
+        Libs.push_back("<Library name index out of range>");
+    }
 
   llvm::stable_sort(Libs);
 




More information about the llvm-commits mailing list