Report an error if a SHT_SYMTAB_SHNDX section has the wrong size.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 24 Aug 2015 21:09:41 +0000 (21:09 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 24 Aug 2015 21:09:41 +0000 (21:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245873 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELF.h
test/Object/Inputs/invalid-xindex-size.elf [new file with mode: 0644]
test/Object/invalid.test

index 9750d3be175cda667a09f5413e3c14ed69b7cb0d..092ac6db0bd78846f724f8a88a9eff70f3cda23f 100644 (file)
@@ -197,9 +197,9 @@ public:
 
   uint64_t getNumSections() const;
   uintX_t getStringTableIndex() const;
-  ELF::Elf64_Word
-  getExtendedSymbolTableIndex(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
-                              ArrayRef<Elf_Word> ShndxTable) const;
+  uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
+                                       const Elf_Shdr *SymTab,
+                                       ArrayRef<Elf_Word> ShndxTable) const;
   const Elf_Ehdr *getHeader() const { return Header; }
   ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
                                        const Elf_Shdr *SymTab,
@@ -220,13 +220,13 @@ typedef ELFFile<ELFType<support::big, false>> ELF32BEFile;
 typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
 
 template <class ELFT>
-ELF::Elf64_Word ELFFile<ELFT>::getExtendedSymbolTableIndex(
+uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex(
     const Elf_Sym *Sym, const Elf_Shdr *SymTab,
     ArrayRef<Elf_Word> ShndxTable) const {
   assert(Sym->st_shndx == ELF::SHN_XINDEX);
   unsigned Index = Sym - symbol_begin(SymTab);
 
-  // FIXME: error checking
+  // The size of the table was checked in getSHNDXTable.
   return ShndxTable[Index];
 }
 
@@ -471,12 +471,22 @@ ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
   assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
   const Elf_Word *ShndxTableBegin =
       reinterpret_cast<const Elf_Word *>(base() + Section.sh_offset);
-  uintX_t Size = Section.sh_offset;
-  if (Size % sizeof(uintX_t))
+  uintX_t Size = Section.sh_size;
+  if (Size % sizeof(uint32_t))
     return object_error::parse_failed;
-  const Elf_Word *ShndxTableEnd = ShndxTableBegin + Size / sizeof(uintX_t);
+  uintX_t NumSymbols = Size / sizeof(uint32_t);
+  const Elf_Word *ShndxTableEnd = ShndxTableBegin + NumSymbols;
   if (reinterpret_cast<const char *>(ShndxTableEnd) > Buf.end())
     return object_error::parse_failed;
+  ErrorOr<const Elf_Shdr *> SymTableOrErr = getSection(Section.sh_link);
+  if (std::error_code EC = SymTableOrErr.getError())
+    return EC;
+  const Elf_Shdr &SymTable = **SymTableOrErr;
+  if (SymTable.sh_type != ELF::SHT_SYMTAB &&
+      SymTable.sh_type != ELF::SHT_DYNSYM)
+    return object_error::parse_failed;
+  if (NumSymbols != (SymTable.sh_size / sizeof(Elf_Sym)))
+    return object_error::parse_failed;
   return ArrayRef<Elf_Word>(ShndxTableBegin, ShndxTableEnd);
 }
 
diff --git a/test/Object/Inputs/invalid-xindex-size.elf b/test/Object/Inputs/invalid-xindex-size.elf
new file mode 100644 (file)
index 0000000..2852b85
Binary files /dev/null and b/test/Object/Inputs/invalid-xindex-size.elf differ
index a4219ed592db6a44c73fccb5b7b94aaf258ce30c..cc5cd68304c6a867986174d9ac9eb9cd28364336 100644 (file)
@@ -48,3 +48,7 @@ INVALID-SECTION-SIZE: Invalid section header entry size (e_shentsize) in ELF hea
 
 RUN: not llvm-readobj -t %p/Inputs/invalid-symbol-table-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SYMTAB-SIZE %s
 INVALID-SYMTAB-SIZE: Invalid symbol table size
+
+
+RUN: not llvm-readobj -t %p/Inputs/invalid-xindex-size.elf 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s
+INVALID-XINDEX-SIZE: Invalid data was encountered while parsing the file.