[RuntimeDyld] Add bounds checking to SectionEntry::advanceStubOffset
authorSanjoy Das <sanjoy@playingwithpointers.com>
Mon, 23 Nov 2015 21:47:46 +0000 (21:47 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Mon, 23 Nov 2015 21:47:46 +0000 (21:47 +0000)
Summary:
Change SectionEntry to keep track of the size of its underlying
allocation, and use that to bounds check advanceStubOffset.

Reviewers: lhames, andrew.w.kaylor, reames

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D14675

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253919 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h

index adf24a87e4194b865c8b2edff7f6623052e12153..93de920209c7fada153890178cda063512c8fe91 100644 (file)
@@ -518,7 +518,8 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
   if (!Addr)
     report_fatal_error("Unable to allocate memory for common symbols!");
   uint64_t Offset = 0;
-  Sections.push_back(SectionEntry("<common symbols>", Addr, CommonSize, 0));
+  Sections.push_back(
+      SectionEntry("<common symbols>", Addr, CommonSize, CommonSize, 0));
   memset(Addr, 0, CommonSize);
 
   DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: "
@@ -643,7 +644,8 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
                  << " Allocate: " << Allocate << "\n");
   }
 
-  Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
+  Sections.push_back(
+      SectionEntry(Name, Addr, DataSize, Allocate, (uintptr_t)pData));
 
   if (Checker)
     Checker->registerSection(Obj.getFileName(), SectionID);
index 2ca0e43c0d914fd47c3670fcd22f107f64205393..fea9b96dce06a2e9506d540c4ea732adc178ee50 100644 (file)
@@ -1770,7 +1770,7 @@ uint64_t RuntimeDyldELF::allocateGOTEntries(unsigned SectionID, unsigned no)
     GOTSectionID = Sections.size();
     // Reserve a section id. We'll allocate the section later
     // once we know the total size
-    Sections.push_back(SectionEntry(".got", nullptr, 0, 0));
+    Sections.push_back(SectionEntry(".got", nullptr, 0, 0, 0));
   }
   uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize();
   CurrentGOTIndex += no;
@@ -1806,7 +1806,8 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
     if (!Addr)
       report_fatal_error("Unable to allocate memory for GOT!");
 
-    Sections[GOTSectionID] = SectionEntry(".got", Addr, TotalSize, 0);
+    Sections[GOTSectionID] =
+        SectionEntry(".got", Addr, TotalSize, TotalSize, 0);
 
     if (Checker)
       Checker->registerSection(Obj.getFileName(), GOTSectionID);
index d005099535fcf47dfab1a0d71e8fcd0f76ee49ea..6838648b89454ab797e4e037543f19279b9b9562 100644 (file)
@@ -69,16 +69,20 @@ class SectionEntry {
   /// relocations (like ARM).
   uintptr_t StubOffset;
 
+  /// The total amount of space allocated for this section.  This includes the
+  /// section size and the maximum amount of space that the stubs can occupy.
+  size_t AllocationSize;
+
   /// ObjAddress - address of the section in the in-memory object file.  Used
   /// for calculating relocations in some object formats (like MachO).
   uintptr_t ObjAddress;
 
 public:
   SectionEntry(StringRef name, uint8_t *address, size_t size,
-               uintptr_t objAddress)
+               size_t allocationSize, uintptr_t objAddress)
       : Name(name), Address(address), Size(size),
         LoadAddress(reinterpret_cast<uintptr_t>(address)), StubOffset(size),
-        ObjAddress(objAddress) {}
+        AllocationSize(allocationSize), ObjAddress(objAddress) {}
 
   StringRef getName() const { return Name; }
 
@@ -86,6 +90,7 @@ public:
 
   /// \brief Return the address of this section with an offset.
   uint8_t *getAddressWithOffset(unsigned OffsetBytes) const {
+    assert(OffsetBytes <= AllocationSize && "Offset out of bounds!");
     return Address + OffsetBytes;
   }
 
@@ -96,12 +101,16 @@ public:
 
   /// \brief Return the load address of this section with an offset.
   uint64_t getLoadAddressWithOffset(unsigned OffsetBytes) const {
+    assert(OffsetBytes <= AllocationSize && "Offset out of bounds!");
     return LoadAddress + OffsetBytes;
   }
 
   uintptr_t getStubOffset() const { return StubOffset; }
 
-  void advanceStubOffset(unsigned StubSize) { StubOffset += StubSize; }
+  void advanceStubOffset(unsigned StubSize) {
+    StubOffset += StubSize;
+    assert(StubOffset <= AllocationSize && "Not enough space allocated!");
+  }
 
   uintptr_t getObjAddress() const { return ObjAddress; }
 };