From: Rafael Espindola Date: Tue, 10 Oct 2017 22:17:49 +0000 (+0000) Subject: Make the ELFFile constructor private. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f80a5f9b0b21a106d5ffeb42371da7a292c0137;p=llvm Make the ELFFile constructor private. 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 --- diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index c3bfa7be289..3debfd84fde 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -83,6 +83,8 @@ public: private: StringRef Buf; + ELFFile(StringRef Object); + public: const Elf_Ehdr *getHeader() const { return reinterpret_cast(base()); @@ -112,7 +114,7 @@ public: Expected getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const; - ELFFile(StringRef Object); + static Expected create(StringRef Object); bool isMipsELF64() const { return getHeader()->e_machine == ELF::EM_MIPS && @@ -345,9 +347,13 @@ ELFFile::getSectionStringTable(Elf_Shdr_Range Sections) const { return getStringTable(&Sections[Index]); } +template ELFFile::ELFFile(StringRef Object) : Buf(Object) {} + template -ELFFile::ELFFile(StringRef Object) : Buf(Object) { - assert(sizeof(Elf_Ehdr) <= Buf.size() && "Invalid buffer"); +Expected> ELFFile::create(StringRef Object) { + if (sizeof(Elf_Ehdr) > Object.size()) + return createError("Invalid buffer"); + return ELFFile(Object); } template diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 260e2ffbdca..2856084e96d 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -211,8 +211,9 @@ public: using Elf_Dyn = typename ELFFile::Elf_Dyn; private: - ELFObjectFile(MemoryBufferRef Object, const Elf_Shdr *DotDynSymSec, - const Elf_Shdr *DotSymtabSec, ArrayRef ShndxTable); + ELFObjectFile(MemoryBufferRef Object, ELFFile EF, + const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec, + ArrayRef ShndxTable); protected: ELFFile EF; @@ -851,7 +852,10 @@ ELFObjectFile::getRela(DataRefImpl Rela) const { template Expected> ELFObjectFile::create(MemoryBufferRef Object) { - ELFFile EF(Object.getBuffer()); + auto EFOrErr = ELFFile::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::create(MemoryBufferRef Object) { } } } - return ELFObjectFile(Object, DotDynSymSec, DotSymtabSec, ShndxTable); + return ELFObjectFile(Object, EF, DotDynSymSec, DotSymtabSec, + ShndxTable); } template -ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, +ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, ELFFile EF, const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec, ArrayRef 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 ELFObjectFile::ELFObjectFile(ELFObjectFile &&Other) - : ELFObjectFile(Other.Data, Other.DotDynSymSec, Other.DotSymtabSec, - Other.ShndxTable) {} + : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec, + Other.DotSymtabSec, Other.ShndxTable) {} template basic_symbol_iterator ELFObjectFile::symbol_begin() const { diff --git a/test/Object/Inputs/invalid-buffer.elf b/test/Object/Inputs/invalid-buffer.elf new file mode 100644 index 00000000000..665d9d1a5cb --- /dev/null +++ b/test/Object/Inputs/invalid-buffer.elf @@ -0,0 +1 @@ +ELF \ No newline at end of file diff --git a/test/Object/invalid.test b/test/Object/invalid.test index 8d2cb72ae7d..66542259b90 100644 --- a/test/Object/invalid.test +++ b/test/Object/invalid.test @@ -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