diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Object/ELF.h | 42 | ||||
-rw-r--r-- | llvm/include/llvm/Object/Error.h | 1 | ||||
-rw-r--r-- | llvm/lib/Object/Error.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Object/corrupt.test | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 29 |
5 files changed, 20 insertions, 56 deletions
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index d01c3cfab16..6a100a55152 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -62,6 +62,8 @@ public: return reinterpret_cast<const uint8_t *>(Buf.data()); } + size_t getBufSize() const { return Buf.size(); } + private: StringRef Buf; @@ -104,18 +106,6 @@ public: Header->getDataEncoding() == ELF::ELFDATA2LSB; } - ErrorOr<const Elf_Dyn *> dynamic_table_begin(const Elf_Phdr *Phdr) const; - ErrorOr<const Elf_Dyn *> dynamic_table_end(const Elf_Phdr *Phdr) const; - ErrorOr<Elf_Dyn_Range> dynamic_table(const Elf_Phdr *Phdr) const { - ErrorOr<const Elf_Dyn *> Begin = dynamic_table_begin(Phdr); - if (std::error_code EC = Begin.getError()) - return EC; - ErrorOr<const Elf_Dyn *> End = dynamic_table_end(Phdr); - if (std::error_code EC = End.getError()) - return EC; - return make_range(*Begin, *End); - } - const Elf_Shdr *section_begin() const; const Elf_Shdr *section_end() const; Elf_Shdr_Range sections() const { @@ -414,34 +404,6 @@ const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const { } template <class ELFT> -ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *> -ELFFile<ELFT>::dynamic_table_begin(const Elf_Phdr *Phdr) const { - if (!Phdr) - return nullptr; - assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header"); - uintX_t Offset = Phdr->p_offset; - if (Offset > Buf.size()) - return object_error::parse_failed; - return reinterpret_cast<const Elf_Dyn *>(base() + Offset); -} - -template <class ELFT> -ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *> -ELFFile<ELFT>::dynamic_table_end(const Elf_Phdr *Phdr) const { - if (!Phdr) - return nullptr; - assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header"); - uintX_t Size = Phdr->p_filesz; - if (Size % sizeof(Elf_Dyn)) - return object_error::elf_invalid_dynamic_table_size; - // FIKME: Check for overflow? - uintX_t End = Phdr->p_offset + Size; - if (End > Buf.size()) - return object_error::parse_failed; - return reinterpret_cast<const Elf_Dyn *>(base() + End); -} - -template <class ELFT> template <typename T> const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const { ErrorOr<const Elf_Shdr *> Sec = getSection(Section); diff --git a/llvm/include/llvm/Object/Error.h b/llvm/include/llvm/Object/Error.h index 0f79a6ed0dd..aa320bb51a4 100644 --- a/llvm/include/llvm/Object/Error.h +++ b/llvm/include/llvm/Object/Error.h @@ -30,7 +30,6 @@ enum class object_error { string_table_non_null_end, invalid_section_index, bitcode_section_not_found, - elf_invalid_dynamic_table_size, macho_small_load_command, macho_load_segment_too_many_sections, macho_load_segment_too_small, diff --git a/llvm/lib/Object/Error.cpp b/llvm/lib/Object/Error.cpp index 7ecc3a19af9..7ca2f12f092 100644 --- a/llvm/lib/Object/Error.cpp +++ b/llvm/lib/Object/Error.cpp @@ -47,8 +47,6 @@ std::string _object_error_category::message(int EV) const { return "Invalid section index"; case object_error::bitcode_section_not_found: return "Bitcode section not found in object file"; - case object_error::elf_invalid_dynamic_table_size: - return "Invalid dynamic table size"; case object_error::macho_small_load_command: return "Mach-O load command with size < 8 bytes"; case object_error::macho_load_segment_too_many_sections: diff --git a/llvm/test/Object/corrupt.test b/llvm/test/Object/corrupt.test index 7208566c25b..3ce7dc7f5e9 100644 --- a/llvm/test/Object/corrupt.test +++ b/llvm/test/Object/corrupt.test @@ -55,7 +55,7 @@ RUN: not llvm-readobj -dyn-relocations \ RUN: %p/Inputs/corrupt-invalid-dynamic-table-size.elf.x86-64 2>&1 | \ RUN: FileCheck --check-prefix=DYN-TABLE-SIZE %s -DYN-TABLE-SIZE: Invalid dynamic table size +DYN-TABLE-SIZE: Invalid entity size RUN: not llvm-readobj -dyn-relocations \ diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 86b6ab635e0..e15a7eb9570 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -127,8 +127,19 @@ private: typedef typename ELFO::Elf_Verdef Elf_Verdef; typedef typename ELFO::Elf_Verdaux Elf_Verdaux; + DynRegionInfo checkDRI(DynRegionInfo DRI) { + if (DRI.Addr < Obj->base() || + (const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize()) + error(llvm::object::object_error::parse_failed); + return DRI; + } + + DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) { + return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize}); + } + DynRegionInfo createDRIFrom(const Elf_Shdr *S) { - return {Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize}; + return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize}); } void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments); @@ -145,12 +156,6 @@ private: Elf_Rel_Range dyn_rels() const; Elf_Rela_Range dyn_relas() const; StringRef getDynamicString(uint64_t Offset) const; - const Elf_Dyn *dynamic_table_begin() const { - return unwrapOrError(Obj->dynamic_table_begin(DynamicProgHeader)); - } - const Elf_Dyn *dynamic_table_end() const { - return unwrapOrError(Obj->dynamic_table_end(DynamicProgHeader)); - } StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb, bool &IsDefault); void LoadVersionMap(); @@ -162,7 +167,7 @@ private: DynRegionInfo DynRelaRegion; DynRegionInfo DynPLTRelRegion; DynRegionInfo DynSymRegion; - const Elf_Phdr *DynamicProgHeader = nullptr; + DynRegionInfo DynamicTable; StringRef DynamicStringTable; StringRef SOName; const Elf_Hash *HashTable = nullptr; @@ -199,7 +204,7 @@ private: public: Elf_Dyn_Range dynamic_table() const { - return unwrapOrError(Obj->dynamic_table(DynamicProgHeader)); + return DynamicTable.getAsRange<Elf_Dyn>(); } Elf_Sym_Range dynamic_symbols() const { @@ -991,7 +996,7 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) SmallVector<const Elf_Phdr *, 4> LoadSegments; for (const Elf_Phdr &Phdr : Obj->program_headers()) { if (Phdr.p_type == ELF::PT_DYNAMIC) { - DynamicProgHeader = &Phdr; + DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn)); continue; } if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0) @@ -1654,8 +1659,8 @@ template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() { template<class ELFT> void ELFDumper<ELFT>::printDynamicTable() { - auto I = dynamic_table_begin(); - auto E = dynamic_table_end(); + auto I = dynamic_table().begin(); + auto E = dynamic_table().end(); if (I == E) return; |