OSDN Git Service

Make the ELFFile constructor private.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 10 Oct 2017 22:17:49 +0000 (22:17 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 10 Oct 2017 22:17:49 +0000 (22:17 +0000)
With this all clients have to use the new create method which returns
an Expected.

Fixes a crash on invalid input.

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

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

index c3bfa7b..3debfd8 100644 (file)
@@ -83,6 +83,8 @@ public:
 private:
   StringRef Buf;
 
+  ELFFile(StringRef Object);
+
 public:
   const Elf_Ehdr *getHeader() const {
     return reinterpret_cast<const Elf_Ehdr *>(base());
@@ -112,7 +114,7 @@ public:
   Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
                                                 const Elf_Shdr *SymTab) const;
 
-  ELFFile(StringRef Object);
+  static Expected<ELFFile> create(StringRef Object);
 
   bool isMipsELF64() const {
     return getHeader()->e_machine == ELF::EM_MIPS &&
@@ -345,9 +347,13 @@ ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
   return getStringTable(&Sections[Index]);
 }
 
+template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
+
 template <class ELFT>
-ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
-  assert(sizeof(Elf_Ehdr) <= Buf.size() && "Invalid buffer");
+Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
+  if (sizeof(Elf_Ehdr) > Object.size())
+    return createError("Invalid buffer");
+  return ELFFile(Object);
 }
 
 template <class ELFT>
index 260e2ff..2856084 100644 (file)
@@ -211,8 +211,9 @@ public:
   using Elf_Dyn = typename ELFFile<ELFT>::Elf_Dyn;
 
 private:
-  ELFObjectFile(MemoryBufferRef Object, const Elf_Shdr *DotDynSymSec,
-                const Elf_Shdr *DotSymtabSec, ArrayRef<Elf_Word> ShndxTable);
+  ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
+                const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
+                ArrayRef<Elf_Word> ShndxTable);
 
 protected:
   ELFFile<ELFT> EF;
@@ -851,7 +852,10 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
 template <class ELFT>
 Expected<ELFObjectFile<ELFT>>
 ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
-  ELFFile<ELFT> EF(Object.getBuffer());
+  auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
+  if (Error E = EFOrErr.takeError())
+    return std::move(E);
+  auto EF = std::move(*EFOrErr);
 
   auto SectionsOrErr = EF.sections();
   if (!SectionsOrErr)
@@ -883,24 +887,25 @@ ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
     }
     }
   }
-  return ELFObjectFile<ELFT>(Object, DotDynSymSec, DotSymtabSec, ShndxTable);
+  return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
+                             ShndxTable);
 }
 
 template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object,
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
                                    const Elf_Shdr *DotDynSymSec,
                                    const Elf_Shdr *DotSymtabSec,
                                    ArrayRef<Elf_Word> ShndxTable)
     : ELFObjectFileBase(
           getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
           Object),
-      EF(Data.getBuffer()), DotDynSymSec(DotDynSymSec),
-      DotSymtabSec(DotSymtabSec), ShndxTable(ShndxTable) {}
+      EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
+      ShndxTable(ShndxTable) {}
 
 template <class ELFT>
 ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
-    : ELFObjectFile(Other.Data, Other.DotDynSymSec, Other.DotSymtabSec,
-                    Other.ShndxTable) {}
+    : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
+                    Other.DotSymtabSec, Other.ShndxTable) {}
 
 template <class ELFT>
 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
diff --git a/test/Object/Inputs/invalid-buffer.elf b/test/Object/Inputs/invalid-buffer.elf
new file mode 100644 (file)
index 0000000..665d9d1
--- /dev/null
@@ -0,0 +1 @@
+\7fELF\ 1\ 1            
\ No newline at end of file
index 8d2cb72..6654225 100644 (file)
@@ -81,3 +81,6 @@ INVALID-SECTION-NUM: section table goes past the end of 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 section offset
+
+RUN: not llvm-readobj -r %p/Inputs/invalid-buffer.elf 2>&1 | FileCheck --check-prefix=INVALID-BUFFER %s
+INVALID-BUFFER: Invalid buffer