[llvm] a10570b - [MachO] Detect overflow in section offset. (#98685)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 17 09:42:58 PDT 2024


Author: Eli Friedman
Date: 2024-07-17T09:42:53-07:00
New Revision: a10570ba91050a394ca7766a6d1386dc17f8acc6

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

LOG: [MachO] Detect overflow in section offset. (#98685)

The section offset field is only 32 bits; if the computed section offset
is larger, make sure we don't emit a corrupt object file.

Added: 
    llvm/test/MC/MachO/section-offset-overflow.s

Modified: 
    llvm/lib/MC/MachObjectWriter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index 53eed0092a5b4..e58e095252d05 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -277,9 +277,12 @@ void MachObjectWriter::writeSection(const MCAssembler &Asm,
     W.write<uint32_t>(VMAddr);      // address
     W.write<uint32_t>(SectionSize); // size
   }
+  assert(isUInt<32>(FileOffset) && "Cannot encode offset of section");
   W.write<uint32_t>(FileOffset);
 
   W.write<uint32_t>(Log2(Section.getAlign()));
+  assert((!NumRelocations || isUInt<32>(RelocationsStart)) &&
+         "Cannot encode offset of relocations");
   W.write<uint32_t>(NumRelocations ? RelocationsStart : 0);
   W.write<uint32_t>(NumRelocations);
   W.write<uint32_t>(Flags);
@@ -775,6 +778,7 @@ void MachObjectWriter::populateAddrSigSection(MCAssembler &Asm) {
 
 uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
   uint64_t StartOffset = W.OS.tell();
+  auto NumBytesWritten = [&] { return W.OS.tell() - StartOffset; };
 
   populateAddrSigSection(Asm);
 
@@ -904,6 +908,18 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
     unsigned Flags = Sec.getTypeAndAttributes();
     if (Sec.hasInstructions())
       Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
+    if (!cast<MCSectionMachO>(Sec).isVirtualSection() &&
+        !isUInt<32>(SectionStart)) {
+      Asm.getContext().reportError(
+          SMLoc(), "cannot encode offset of section; object file too large");
+      return NumBytesWritten();
+    }
+    if (NumRelocs && !isUInt<32>(RelocTableEnd)) {
+      Asm.getContext().reportError(
+          SMLoc(),
+          "cannot encode offset of relocations; object file too large");
+      return NumBytesWritten();
+    }
     writeSection(Asm, Sec, getSectionAddress(&Sec), SectionStart, Flags,
                  RelocTableEnd, NumRelocs);
     RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
@@ -1088,7 +1104,7 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
     StringTable.write(W.OS);
   }
 
-  return W.OS.tell() - StartOffset;
+  return NumBytesWritten();
 }
 
 std::unique_ptr<MCObjectWriter>

diff  --git a/llvm/test/MC/MachO/section-offset-overflow.s b/llvm/test/MC/MachO/section-offset-overflow.s
new file mode 100644
index 0000000000000..f652cdb9f7e5c
--- /dev/null
+++ b/llvm/test/MC/MachO/section-offset-overflow.s
@@ -0,0 +1,9 @@
+// RUN: not llvm-mc -triple x86_64-apple-macosx -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s
+
+// CHECK: error: cannot encode offset of section
+
+        .data
+        .long 1
+        .zero 0x100000000
+        .const
+        .long 1


        


More information about the llvm-commits mailing list