Add error handling to getEntry.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 3 Nov 2016 18:05:33 +0000 (18:05 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 3 Nov 2016 18:05:33 +0000 (18:05 +0000)
Issue found by inspection.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285951 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELF.h
test/Object/Inputs/invalid-rel-sym.elf [new file with mode: 0644]
test/Object/invalid.test
tools/llvm-readobj/ARMEHABIPrinter.h
tools/llvm-readobj/ELFDumper.cpp
tools/obj2yaml/elf2yaml.cpp

index d8adb30ee32a23a8bc19481a271e8a465947c03f..33a3b75b47bc6969d695dff5db4607e5c570e067 100644 (file)
@@ -75,7 +75,7 @@ public:
   template <typename T>
   ErrorOr<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
   template <typename T>
-  const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
+  ErrorOr<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
 
   ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const;
   ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
@@ -93,8 +93,8 @@ public:
                              SmallVectorImpl<char> &Result) const;
 
   /// \brief Get the symbol for a given relocation.
-  const Elf_Sym *getRelocationSymbol(const Elf_Rel *Rel,
-                                     const Elf_Shdr *SymTab) const;
+  ErrorOr<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
+                                               const Elf_Shdr *SymTab) const;
 
   ELFFile(StringRef Object, std::error_code &EC);
 
@@ -310,7 +310,7 @@ void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
 }
 
 template <class ELFT>
-const typename ELFT::Sym *
+ErrorOr<const typename ELFT::Sym *>
 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
                                    const Elf_Shdr *SymTab) const {
   uint32_t Index = Rel->getSymbol(isMips64EL());
@@ -413,10 +413,14 @@ ErrorOr<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
 
 template <class ELFT>
 template <typename T>
-const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
-                                 uint32_t Entry) const {
-  return reinterpret_cast<const T *>(base() + Section->sh_offset +
-                                     (Entry * Section->sh_entsize));
+ErrorOr<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
+                                           uint32_t Entry) const {
+  if (sizeof(T) != Section->sh_entsize)
+    return object_error::parse_failed;
+  size_t Pos = Section->sh_offset + Entry * sizeof(T);
+  if (Pos + sizeof(T) > Buf.size())
+    return object_error::parse_failed;
+  return reinterpret_cast<const T *>(base() + Pos);
 }
 
 template <class ELFT>
diff --git a/test/Object/Inputs/invalid-rel-sym.elf b/test/Object/Inputs/invalid-rel-sym.elf
new file mode 100644 (file)
index 0000000..d00ddd5
Binary files /dev/null and b/test/Object/Inputs/invalid-rel-sym.elf differ
index c124ff05ed59f55d93931426a4aa860cb3eb8c73..ae6b3feb5282c8d4b83b848653c050805ba3af68 100644 (file)
@@ -78,3 +78,6 @@ INVALID-SECTION-SIZE2: Invalid data was encountered while parsing the file.
 
 RUN: not llvm-readobj -t %p/Inputs/invalid-sections-num.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-NUM %s
 INVALID-SECTION-NUM: Invalid data was encountered while parsing the file.
+
+RUN: not llvm-readobj -r %p/Inputs/invalid-rel-sym.elf 2>&1 | FileCheck --check-prefix=INVALID-REL-SYM %s
+INVALID-REL-SYM: Invalid data was encountered while parsing the file.
index 1e0e8714b6e3b3d482250a06ebe06b6c97ccafe3..2e10d8a917fe411f78b341e9dd912576dd785e65 100644 (file)
@@ -396,7 +396,8 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
       RelA.r_info = R.r_info;
       RelA.r_addend = 0;
 
-      const Elf_Sym *Symbol = ELF->getRelocationSymbol(&RelA, SymTab);
+      const Elf_Sym *Symbol =
+          unwrapOrError(ELF->getRelocationSymbol(&RelA, SymTab));
 
       ErrorOr<const Elf_Shdr *> Ret =
           ELF->getSection(Symbol, SymTab, ShndxTable);
index edb35642395bb619bae1ee1ac8b35d13f4703d59..bde7a6ebbea029eea89f72a1054464002e211ace 100644 (file)
@@ -647,8 +647,8 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
                        sizeof(Elf_Sym);
 
   // Get the corresponding version index entry
-  const Elf_Versym *vs =
-      Obj->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
+  const Elf_Versym *vs = unwrapOrError(
+      Obj->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index));
   size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
 
   // Special markers for unversioned symbols.
@@ -2068,7 +2068,8 @@ template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
     switch (PLTRelShdr->sh_type) {
     case ELF::SHT_REL:
       for (const Elf_Rel &Rel : Obj->rels(PLTRelShdr)) {
-        const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTable);
+        const Elf_Sym *Sym =
+            unwrapOrError(Obj->getRelocationSymbol(&Rel, SymTable));
         printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym);
         if (++It == PLTEnd)
           break;
@@ -2076,7 +2077,8 @@ template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
       break;
     case ELF::SHT_RELA:
       for (const Elf_Rela &Rel : Obj->relas(PLTRelShdr)) {
-        const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTable);
+        const Elf_Sym *Sym =
+            unwrapOrError(Obj->getRelocationSymbol(&Rel, SymTable));
         printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym);
         if (++It == PLTEnd)
           break;
@@ -2428,7 +2430,7 @@ template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
       const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link));
       StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
       const Elf_Sym *Signature =
-          Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info);
+          unwrapOrError(Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info));
       ArrayRef<Elf_Word> Data = unwrapOrError(
           Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
       StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
@@ -2465,7 +2467,7 @@ void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
   // fixed width.
   Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
   Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
-  Sym = Obj->getRelocationSymbol(&R, SymTab);
+  Sym = unwrapOrError(Obj->getRelocationSymbol(&R, SymTab));
   if (Sym && Sym->getType() == ELF::STT_SECTION) {
     const Elf_Shdr *Sec = unwrapOrError(
         Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
@@ -3332,7 +3334,8 @@ void LLVMStyle<ELFT>::printGroupSections(const ELFO *Obj) {
       HasGroups = true;
       const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link));
       StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab));
-      const Elf_Sym *Sym = Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info);
+      const Elf_Sym *Sym =
+          unwrapOrError(Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info));
       auto Data = unwrapOrError(
           Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
       DictScope D(W, "Group");
@@ -3406,7 +3409,7 @@ void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel,
   SmallString<32> RelocName;
   Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
   StringRef TargetName;
-  const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab);
+  const Elf_Sym *Sym = unwrapOrError(Obj->getRelocationSymbol(&Rel, SymTab));
   if (Sym && Sym->getType() == ELF::STT_SECTION) {
     const Elf_Shdr *Sec = unwrapOrError(
         Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
index 8da8aa10c118fe1418bc86a63fe1ce5213eabfa9..dbb8c7d436b1c25d9a99ba6491d6c8c51c01dc8c 100644 (file)
@@ -216,7 +216,10 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
   R.Offset = Rel->r_offset;
   R.Addend = 0;
 
-  const Elf_Sym *Sym = Obj.getRelocationSymbol(Rel, SymTab);
+  auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
+  if (std::error_code EC = SymOrErr.getError())
+    return EC;
+  const Elf_Sym *Sym = *SymOrErr;
   ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection(SymTab->sh_link);
   if (std::error_code EC = StrTabSec.getError())
     return EC;