diff options
author | Eli Friedman <efriedma@quicinc.com> | 2024-07-17 09:42:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-17 09:42:53 -0700 |
commit | a10570ba91050a394ca7766a6d1386dc17f8acc6 (patch) | |
tree | 705d0788e3d1e9b415f2f461d04ecee627ba5c43 /llvm/lib/MC/MachObjectWriter.cpp | |
parent | e5ccc7136dab209d769cc97efd7f1596c12d5bec (diff) | |
download | llvm-a10570ba91050a394ca7766a6d1386dc17f8acc6.zip llvm-a10570ba91050a394ca7766a6d1386dc17f8acc6.tar.gz llvm-a10570ba91050a394ca7766a6d1386dc17f8acc6.tar.bz2 |
[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.
Diffstat (limited to 'llvm/lib/MC/MachObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/MachObjectWriter.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index 53eed00..e58e095 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> |