From 1c12cc02fd95b3049f2d2f751b1611b30e565529 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 20 Jul 2015 20:07:50 +0000 Subject: [PATCH] Remove Elf_Rela_Iter and Elf_Rel_Iter. Use just the pointers and check for invalid relocation sections. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242700 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELF.h | 68 +++++++++++------- ...corrupt-invalid-relocation-size.elf.x86-64 | Bin 0 -> 2160 bytes test/Object/corrupt.test | 7 ++ tools/llvm-readobj/ARMEHABIPrinter.h | 12 ++-- tools/llvm-readobj/ELFDumper.cpp | 46 +++++------- 5 files changed, 73 insertions(+), 60 deletions(-) create mode 100755 test/Object/Inputs/corrupt-invalid-relocation-size.elf.x86-64 diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 509355b105d..e5a419cd650 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -142,8 +142,6 @@ public: typedef Elf_Hash_Impl Elf_Hash; typedef ELFEntityIterator Elf_Dyn_Iter; typedef iterator_range Elf_Dyn_Range; - typedef ELFEntityIterator Elf_Rela_Iter; - typedef ELFEntityIterator Elf_Rel_Iter; typedef iterator_range Elf_Shdr_Range; /// \brief Archive files are 2 byte aligned, so we need this for @@ -311,40 +309,58 @@ public: return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); } - Elf_Rela_Iter dyn_rela_begin() const { - if (DynRelaRegion.Addr) - return Elf_Rela_Iter(DynRelaRegion.EntSize, - (const char *)DynRelaRegion.Addr); - return Elf_Rela_Iter(0, nullptr); + const Elf_Rela *dyn_rela_begin() const { + if (DynRelaRegion.Size && DynRelaRegion.EntSize != sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation entry size"); + return reinterpret_cast(DynRelaRegion.Addr); } - Elf_Rela_Iter dyn_rela_end() const { - if (DynRelaRegion.Addr) - return Elf_Rela_Iter( - DynRelaRegion.EntSize, - (const char *)DynRelaRegion.Addr + DynRelaRegion.Size); - return Elf_Rela_Iter(0, nullptr); + const Elf_Rela *dyn_rela_end() const { + uint64_t Size = DynRelaRegion.Size; + if (Size % sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation table size"); + return dyn_rela_begin() + Size / sizeof(Elf_Rela); } - Elf_Rela_Iter rela_begin(const Elf_Shdr *sec) const { - return Elf_Rela_Iter(sec->sh_entsize, - (const char *)(base() + sec->sh_offset)); + typedef iterator_range Elf_Rela_Range; + + Elf_Rela_Range dyn_relas() const { + return make_range(dyn_rela_begin(), dyn_rela_end()); + } + + const Elf_Rela *rela_begin(const Elf_Shdr *sec) const { + if (sec->sh_entsize != sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation entry size"); + return reinterpret_cast(base() + sec->sh_offset); + } + + const Elf_Rela *rela_end(const Elf_Shdr *sec) const { + uint64_t Size = sec->sh_size; + if (Size % sizeof(Elf_Rela)) + report_fatal_error("Invalid relocation table size"); + return rela_begin(sec) + Size / sizeof(Elf_Rela); + } + + Elf_Rela_Range relas(const Elf_Shdr *Sec) const { + return make_range(rela_begin(Sec), rela_end(Sec)); } - Elf_Rela_Iter rela_end(const Elf_Shdr *sec) const { - return Elf_Rela_Iter( - sec->sh_entsize, - (const char *)(base() + sec->sh_offset + sec->sh_size)); + const Elf_Rel *rel_begin(const Elf_Shdr *sec) const { + if (sec->sh_entsize != sizeof(Elf_Rel)) + report_fatal_error("Invalid relocation entry size"); + return reinterpret_cast(base() + sec->sh_offset); } - Elf_Rel_Iter rel_begin(const Elf_Shdr *sec) const { - return Elf_Rel_Iter(sec->sh_entsize, - (const char *)(base() + sec->sh_offset)); + const Elf_Rel *rel_end(const Elf_Shdr *sec) const { + uint64_t Size = sec->sh_size; + if (Size % sizeof(Elf_Rel)) + report_fatal_error("Invalid relocation table size"); + return rel_begin(sec) + Size / sizeof(Elf_Rel); } - Elf_Rel_Iter rel_end(const Elf_Shdr *sec) const { - return Elf_Rel_Iter(sec->sh_entsize, - (const char *)(base() + sec->sh_offset + sec->sh_size)); + typedef iterator_range Elf_Rel_Range; + Elf_Rel_Range rels(const Elf_Shdr *Sec) const { + return make_range(rel_begin(Sec), rel_end(Sec)); } /// \brief Iterate over program header table. diff --git a/test/Object/Inputs/corrupt-invalid-relocation-size.elf.x86-64 b/test/Object/Inputs/corrupt-invalid-relocation-size.elf.x86-64 new file mode 100755 index 0000000000000000000000000000000000000000..2798ab34e17478d05d4c968efc1b7b336ad3f26b GIT binary patch literal 2160 zcmcIk%We}v5NtaRgtr3%@j66E2#{bE-#8!?C)g3fBtnD(Tvi*_vLpF{ybFrC@B#b) zpTUtMpW;t2H{X`7*)GSK*hmP`l3mj^)!RM2J^Q8Bs22+bp)JW%Ir2m{Y~y>03UH65 zr2m)XqMTA1TN}3RoL#_QTfj?8!e$($k%ZxXl7vYb4N|3gasFK7LH}?Z z^dG)&sBvuPM9-`>PWH8Qcamk&iP?wi#-A~~VTk9#)=YmccZGVs<8QW) zKEQ6};A+S6$82%7_g{hU-%EmC;*7xUoj20zcjC25P^ox2-_6TkmWg)`^si9VE?GX# z7sj?wToLx2{ko_8yt#Vd_>*(BzJPzSfEP~Ev$s3dm(RB(+-~e{RvY1Nz5cqk7w%Oz z8@2FH(-)-8!&HJ+KmQ9pbabI3DnUH#CFwwdL9-LVk)YR4n?bAhQPrLJ(WmAhIp`}5 z;jk+~J4)Kli@FEzB}m#Do<{q+A`ZLGcNalV^zXK%kHC!bGr+ke9$E_Q<5l|ee^WW! zHO6zUiJWVdIP=CqUMS0Z3jybzc;7`G-BsqtJi_ki4{PQhSpp*Gh=W^WrO3=;x_2U-&1 | \ RUN: FileCheck --check-prefix=VIRTADDR %s VIRTADDR: Virtual address is not in any segment + + +RUN: not llvm-readobj -dyn-relocations \ +RUN: %p/Inputs/corrupt-invalid-relocation-size.elf.x86-64 2>&1 | \ +RUN: FileCheck --check-prefix=RELOC %s + +RELOC: Invalid relocation entry size diff --git a/tools/llvm-readobj/ARMEHABIPrinter.h b/tools/llvm-readobj/ARMEHABIPrinter.h index dd2490d503d..b223770e1f7 100644 --- a/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/tools/llvm-readobj/ARMEHABIPrinter.h @@ -310,8 +310,7 @@ class PrinterContext { typedef typename object::ELFFile::Elf_Sym Elf_Sym; typedef typename object::ELFFile::Elf_Shdr Elf_Shdr; - - typedef typename object::ELFFile::Elf_Rel_Iter Elf_Rel_iterator; + typedef typename object::ELFFile::Elf_Rel Elf_Rel; static const size_t IndexTableEntrySize; @@ -366,12 +365,11 @@ PrinterContext::FindExceptionTable(unsigned IndexSectionIndex, for (const Elf_Shdr &Sec : ELF->sections()) { if (Sec.sh_type == ELF::SHT_REL && Sec.sh_info == IndexSectionIndex) { - for (Elf_Rel_iterator RI = ELF->rel_begin(&Sec), RE = ELF->rel_end(&Sec); - RI != RE; ++RI) { - if (RI->r_offset == static_cast(IndexTableOffset)) { + for (const Elf_Rel &R : ELF->rels(&Sec)) { + if (R.r_offset == static_cast(IndexTableOffset)) { typename object::ELFFile::Elf_Rela RelA; - RelA.r_offset = RI->r_offset; - RelA.r_info = RI->r_info; + RelA.r_offset = R.r_offset; + RelA.r_info = R.r_info; RelA.r_addend = 0; std::pair Symbol = diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 1cd638c5415..df85e7631f7 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -689,29 +689,25 @@ template void ELFDumper::printDynamicRelocations() { W.startLine() << "Dynamic Relocations {\n"; W.indent(); - for (typename ELFO::Elf_Rela_Iter RelI = Obj->dyn_rela_begin(), - RelE = Obj->dyn_rela_end(); - RelI != RelE; ++RelI) { + for (const typename ELFO::Elf_Rela &Rel : Obj->dyn_relas()) { SmallString<32> RelocName; - Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName); + Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); StringRef SymbolName; - uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL()); + uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL()); const typename ELFO::Elf_Sym *Sym = Obj->dynamic_symbol_begin() + SymIndex; SymbolName = errorOrDefault(Obj->getSymbolName(Sym, true)); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); - W.printHex("Offset", RelI->r_offset); - W.printNumber("Type", RelocName, (int)RelI->getType(Obj->isMips64EL())); + W.printHex("Offset", Rel.r_offset); + W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); - W.printHex("Addend", RelI->r_addend); + W.printHex("Addend", Rel.r_addend); } else { raw_ostream& OS = W.startLine(); - OS << W.hex(RelI->r_offset) - << " " << RelocName - << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << " " << W.hex(RelI->r_addend) - << "\n"; + OS << W.hex(Rel.r_offset) << " " << RelocName << " " + << (SymbolName.size() > 0 ? SymbolName : "-") << " " + << W.hex(Rel.r_addend) << "\n"; } } W.unindent(); @@ -722,22 +718,17 @@ template void ELFDumper::printRelocations(const Elf_Shdr *Sec) { switch (Sec->sh_type) { case ELF::SHT_REL: - for (typename ELFO::Elf_Rel_Iter RI = Obj->rel_begin(Sec), - RE = Obj->rel_end(Sec); - RI != RE; ++RI) { + for (const typename ELFO::Elf_Rel &R : Obj->rels(Sec)) { typename ELFO::Elf_Rela Rela; - Rela.r_offset = RI->r_offset; - Rela.r_info = RI->r_info; + Rela.r_offset = R.r_offset; + Rela.r_info = R.r_info; Rela.r_addend = 0; printRelocation(Sec, Rela); } break; case ELF::SHT_RELA: - for (typename ELFO::Elf_Rela_Iter RI = Obj->rela_begin(Sec), - RE = Obj->rela_end(Sec); - RI != RE; ++RI) { - printRelocation(Sec, *RI); - } + for (const typename ELFO::Elf_Rela &R : Obj->relas(Sec)) + printRelocation(Sec, R); break; } } @@ -1371,8 +1362,8 @@ template void MipsGOTParser::parsePLT() { switch (PLTRelShdr->sh_type) { case ELF::SHT_REL: - for (typename ObjectFile::Elf_Rel_Iter RI = Obj->rel_begin(PLTRelShdr), - RE = Obj->rel_end(PLTRelShdr); + for (const typename ObjectFile::Elf_Rel *RI = Obj->rel_begin(PLTRelShdr), + *RE = Obj->rel_end(PLTRelShdr); RI != RE && It != PLTEnd; ++RI, ++It) { const Elf_Sym *Sym = Obj->getRelocationSymbol(&*PLTRelShdr, &*RI).second; @@ -1380,8 +1371,9 @@ template void MipsGOTParser::parsePLT() { } break; case ELF::SHT_RELA: - for (typename ObjectFile::Elf_Rela_Iter RI = Obj->rela_begin(PLTRelShdr), - RE = Obj->rela_end(PLTRelShdr); + for (const typename ObjectFile::Elf_Rela + *RI = Obj->rela_begin(PLTRelShdr), + *RE = Obj->rela_end(PLTRelShdr); RI != RE && It != PLTEnd; ++RI, ++It) { const Elf_Sym *Sym = Obj->getRelocationSymbol(&*PLTRelShdr, &*RI).second; -- 2.34.1