[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