forked from OSchip/llvm-project
[Orc] Always check mapped sections for ELFDebugObject are in bounds of working memory buffer
As stated in the JITLink user guide: Do not assume that the input object is well formed. https://llvm.org/docs/JITLink.html#tips-for-jitlink-backend-developers
This commit is contained in:
parent
6a3a386c6f
commit
265bc5af7b
|
@ -20,7 +20,7 @@
|
|||
#include "llvm/ExecutionEngine/Orc/TPCDebugObjectRegistrar.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/Memory.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/MemoryBufferRef.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
void setTargetMemoryRange(SectionRange Range) override;
|
||||
void dump(raw_ostream &OS, StringRef Name) override;
|
||||
|
||||
Error validateInBounds(StringRef Buffer, const char *Name) const;
|
||||
|
||||
private:
|
||||
typename ELFT::Shdr *Header;
|
||||
|
||||
|
@ -64,15 +66,6 @@ void ELFDebugObjectSection<ELFT>::setTargetMemoryRange(SectionRange Range) {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename ELFT>
|
||||
void ELFDebugObjectSection<ELFT>::dump(raw_ostream &OS, StringRef Name) {
|
||||
if (auto Addr = static_cast<JITTargetAddress>(Header->sh_addr)) {
|
||||
OS << formatv(" {0:x16} {1}\n", Addr, Name);
|
||||
} else {
|
||||
OS << formatv(" {0}\n", Name);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ELFT>
|
||||
bool ELFDebugObjectSection<ELFT>::isTextOrDataSection() const {
|
||||
switch (Header->sh_type) {
|
||||
|
@ -83,6 +76,37 @@ bool ELFDebugObjectSection<ELFT>::isTextOrDataSection() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename ELFT>
|
||||
Error ELFDebugObjectSection<ELFT>::validateInBounds(StringRef Buffer,
|
||||
const char *Name) const {
|
||||
const uint8_t *Start = Buffer.bytes_begin();
|
||||
const uint8_t *End = Buffer.bytes_end();
|
||||
const uint8_t *HeaderPtr = reinterpret_cast<uint8_t *>(Header);
|
||||
if (HeaderPtr < Start || HeaderPtr + sizeof(typename ELFT::Shdr) > End)
|
||||
return make_error<StringError>(
|
||||
formatv("{0} section header at {1:x16} not within bounds of the "
|
||||
"given debug object buffer [{2:x16} - {3:x16}]",
|
||||
Name, &Header->sh_addr, Start, End),
|
||||
inconvertibleErrorCode());
|
||||
if (Header->sh_offset + Header->sh_size > Buffer.size())
|
||||
return make_error<StringError>(
|
||||
formatv("{0} section data [{1:x16} - {2:x16}] not within bounds of "
|
||||
"the given debug object buffer [{3:x16} - {4:x16}]",
|
||||
Name, Start + Header->sh_offset,
|
||||
Start + Header->sh_offset + Header->sh_size, Start, End),
|
||||
inconvertibleErrorCode());
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <typename ELFT>
|
||||
void ELFDebugObjectSection<ELFT>::dump(raw_ostream &OS, StringRef Name) {
|
||||
if (auto Addr = static_cast<JITTargetAddress>(Header->sh_addr)) {
|
||||
OS << formatv(" {0:x16} {1}\n", Addr, Name);
|
||||
} else {
|
||||
OS << formatv(" {0}\n", Name);
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr sys::Memory::ProtectionFlags ReadOnly =
|
||||
static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ);
|
||||
|
||||
|
@ -162,8 +186,9 @@ protected:
|
|||
Expected<std::unique_ptr<Allocation>>
|
||||
finalizeWorkingMemory(JITLinkContext &Ctx) override;
|
||||
|
||||
template <typename ELFT>
|
||||
Error recordSection(StringRef Name,
|
||||
std::unique_ptr<DebugObjectSection> Section);
|
||||
std::unique_ptr<ELFDebugObjectSection<ELFT>> Section);
|
||||
DebugObjectSection *getSection(StringRef Name);
|
||||
|
||||
private:
|
||||
|
@ -319,8 +344,11 @@ void ELFDebugObject::reportSectionTargetMemoryRange(StringRef Name,
|
|||
DebugObjSection->setTargetMemoryRange(TargetMem);
|
||||
}
|
||||
|
||||
template <typename ELFT>
|
||||
Error ELFDebugObject::recordSection(
|
||||
StringRef Name, std::unique_ptr<DebugObjectSection> Section) {
|
||||
StringRef Name, std::unique_ptr<ELFDebugObjectSection<ELFT>> Section) {
|
||||
if (Error Err = Section->validateInBounds(this->getBuffer(), Name.data()))
|
||||
return Err;
|
||||
auto ItInserted = Sections.try_emplace(Name, std::move(Section));
|
||||
if (!ItInserted.second)
|
||||
return make_error<StringError>("Duplicate section",
|
||||
|
|
Loading…
Reference in New Issue