Skip to content

Commit a10570b

Browse files
[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.
1 parent e5ccc71 commit a10570b

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

llvm/lib/MC/MachObjectWriter.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,12 @@ void MachObjectWriter::writeSection(const MCAssembler &Asm,
277277
W.write<uint32_t>(VMAddr); // address
278278
W.write<uint32_t>(SectionSize); // size
279279
}
280+
assert(isUInt<32>(FileOffset) && "Cannot encode offset of section");
280281
W.write<uint32_t>(FileOffset);
281282

282283
W.write<uint32_t>(Log2(Section.getAlign()));
284+
assert((!NumRelocations || isUInt<32>(RelocationsStart)) &&
285+
"Cannot encode offset of relocations");
283286
W.write<uint32_t>(NumRelocations ? RelocationsStart : 0);
284287
W.write<uint32_t>(NumRelocations);
285288
W.write<uint32_t>(Flags);
@@ -775,6 +778,7 @@ void MachObjectWriter::populateAddrSigSection(MCAssembler &Asm) {
775778

776779
uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
777780
uint64_t StartOffset = W.OS.tell();
781+
auto NumBytesWritten = [&] { return W.OS.tell() - StartOffset; };
778782

779783
populateAddrSigSection(Asm);
780784

@@ -904,6 +908,18 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
904908
unsigned Flags = Sec.getTypeAndAttributes();
905909
if (Sec.hasInstructions())
906910
Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
911+
if (!cast<MCSectionMachO>(Sec).isVirtualSection() &&
912+
!isUInt<32>(SectionStart)) {
913+
Asm.getContext().reportError(
914+
SMLoc(), "cannot encode offset of section; object file too large");
915+
return NumBytesWritten();
916+
}
917+
if (NumRelocs && !isUInt<32>(RelocTableEnd)) {
918+
Asm.getContext().reportError(
919+
SMLoc(),
920+
"cannot encode offset of relocations; object file too large");
921+
return NumBytesWritten();
922+
}
907923
writeSection(Asm, Sec, getSectionAddress(&Sec), SectionStart, Flags,
908924
RelocTableEnd, NumRelocs);
909925
RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
@@ -1088,7 +1104,7 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
10881104
StringTable.write(W.OS);
10891105
}
10901106

1091-
return W.OS.tell() - StartOffset;
1107+
return NumBytesWritten();
10921108
}
10931109

10941110
std::unique_ptr<MCObjectWriter>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not llvm-mc -triple x86_64-apple-macosx -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s
2+
3+
// CHECK: error: cannot encode offset of section
4+
5+
.data
6+
.long 1
7+
.zero 0x100000000
8+
.const
9+
.long 1

0 commit comments

Comments
 (0)