Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion llvm/lib/ObjectYAML/MachOEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,15 @@ void MachOWriter::writeLoadCommands(raw_ostream &OS) {

// Fill remaining bytes with 0. This will only get hit in partially
// specified test cases.
auto BytesRemaining = LC.Data.load_command_data.cmdsize - BytesWritten;
// Prevent integer underflow if BytesWritten exceeds cmdsize.
if (BytesWritten > LC.Data.load_command_data.cmdsize) {
errs() << "warning: load command " << LC.Data.load_command_data.cmd
<< " cmdsize too small (" << LC.Data.load_command_data.cmdsize
<< " bytes) for actual size (" << BytesWritten << " bytes)\n";
}
auto BytesRemaining = (BytesWritten < LC.Data.load_command_data.cmdsize)
? LC.Data.load_command_data.cmdsize - BytesWritten
: 0;
if (BytesRemaining > 0) {
ZeroFillBytes(OS, BytesRemaining);
}
Expand Down
33 changes: 33 additions & 0 deletions llvm/test/ObjectYAML/MachO/segment-cmdsize-too-small.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Test that yaml2obj handles cmdsize that is too small for LC_SEGMENT_64
## without crashing (due to integer underflow).

# RUN: yaml2obj %s -o %t 2>&1 | FileCheck %s --check-prefix=WARNING
# RUN: not llvm-readobj --file-headers %t 2>&1 | FileCheck %s --check-prefix=MALFORMED

# WARNING: warning: load command 25 cmdsize too small (56 bytes) for actual size (72 bytes)

# MALFORMED: error: {{.*}}: truncated or malformed object (load command 0 LC_SEGMENT_64 cmdsize too small)

--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x00000001
ncmds: 1
sizeofcmds: 56
flags: 0x00002000
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 56 ## Should be 72 for LC_SEGMENT_64
segname: '__TEXT'
vmaddr: 0x1000
vmsize: 0x10
fileoff: 0
filesize: 0
maxprot: 7
initprot: 5
nsects: 0
flags: 0
...