[llvm] 265bc5a - [Orc] Always check mapped sections for ELFDebugObject are in bounds of working memory buffer

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 9 05:03:14 PST 2021


Author: Stefan Gränitz
Date: 2021-03-09T14:01:50+01:00
New Revision: 265bc5af7b3be612e170c66521a120b754128818

URL: https://github.com/llvm/llvm-project/commit/265bc5af7b3be612e170c66521a120b754128818
DIFF: https://github.com/llvm/llvm-project/commit/265bc5af7b3be612e170c66521a120b754128818.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h
    llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h b/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h
index 51efd8a6cd5a..68ffbb4a5ed3 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h
@@ -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>

diff  --git a/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp
index 9380c9db486f..8ed0a5a7240e 100644
--- a/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp
@@ -50,6 +50,8 @@ class ELFDebugObjectSection : public DebugObjectSection {
   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 @@ class ELFDebugObject : public DebugObject {
   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",


        


More information about the llvm-commits mailing list