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.
llvm-svn: 315376
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h
index c3bfa7b..3debfd8 100644
--- a/llvm/include/llvm/Object/ELF.h
+++ b/llvm/include/llvm/Object/ELF.h
@@ -83,6 +83,8 @@
private:
StringRef Buf;
+ ELFFile(StringRef Object);
+
public:
const Elf_Ehdr *getHeader() const {
return reinterpret_cast<const Elf_Ehdr *>(base());
@@ -112,7 +114,7 @@
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 @@
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>
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 260e2ff..2856084 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -211,8 +211,9 @@
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 @@
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 @@
}
}
}
- 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/llvm/test/Object/Inputs/invalid-buffer.elf b/llvm/test/Object/Inputs/invalid-buffer.elf
new file mode 100644
index 0000000..665d9d1
--- /dev/null
+++ b/llvm/test/Object/Inputs/invalid-buffer.elf
@@ -0,0 +1 @@
+ELF
\ No newline at end of file
diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test
index 8d2cb72..6654225 100644
--- a/llvm/test/Object/invalid.test
+++ b/llvm/test/Object/invalid.test
@@ -81,3 +81,6 @@
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