Skip to content

Commit 074da9b

Browse files
committedJun 4, 2015
[Object, MachO] Don't crash on invalid MachO segment load commands.
Summary: Properly report the error in segment load commands from MachOObjectFile constructor instead of crashing the program. Adjust the test case accordingly. Test Plan: regression test suite Reviewers: rafael, filcab Subscribers: llvm-commits llvm-svn: 239081
1 parent de5a94a commit 074da9b

File tree

4 files changed

+23
-13
lines changed

4 files changed

+23
-13
lines changed
 

‎llvm/include/llvm/Object/Error.h

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ enum class object_error {
2929
unexpected_eof,
3030
bitcode_section_not_found,
3131
macho_small_load_command,
32+
macho_load_segment_too_many_sections,
33+
macho_load_segment_too_small,
3234
};
3335

3436
inline std::error_code make_error_code(object_error e) {

‎llvm/lib/Object/Error.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ std::string _object_error_category::message(int EV) const {
4646
return "Bitcode section not found in object file";
4747
case object_error::macho_small_load_command:
4848
return "Mach-O load command with size < 8 bytes";
49+
case object_error::macho_load_segment_too_many_sections:
50+
return "Mach-O segment load command contains too many sections";
51+
case object_error::macho_load_segment_too_small:
52+
return "Mach-O segment load command size is too small";
4953
}
5054
llvm_unreachable("An enumerator of object_error does not have a message "
5155
"defined.");

‎llvm/lib/Object/MachOObjectFile.cpp

+15-11
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,16 @@ static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
6666
}
6767

6868
template <typename SegmentCmd>
69-
static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S,
70-
uint32_t Cmdsize) {
69+
static ErrorOr<uint32_t> getSegmentLoadCommandNumSections(const SegmentCmd &S,
70+
uint32_t Cmdsize) {
7171
const unsigned SectionSize = sizeof(SegmentCmd);
7272
if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
7373
S.nsects * SectionSize > Cmdsize - sizeof(S))
74-
report_fatal_error(
75-
"Number of sections too large for size of load command.");
74+
return object_error::macho_load_segment_too_many_sections;
7675
return S.nsects;
7776
}
7877

79-
static uint32_t
78+
static ErrorOr<uint32_t>
8079
getSegmentLoadCommandNumSections(const MachOObjectFile *O,
8180
const MachOObjectFile::LoadCommandInfo &L) {
8281
if (O->is64Bit())
@@ -306,14 +305,19 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
306305
}
307306
UuidLoadCmd = Load.Ptr;
308307
} else if (Load.C.cmd == SegmentLoadType) {
309-
const unsigned SegmentLoadSize = this->is64Bit()
308+
const unsigned SegmentLoadSize = is64Bit()
310309
? sizeof(MachO::segment_command_64)
311310
: sizeof(MachO::segment_command);
312-
if (Load.C.cmdsize < SegmentLoadSize)
313-
report_fatal_error("Segment load command size is too small.");
314-
315-
uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
316-
for (unsigned J = 0; J < NumSections; ++J) {
311+
if (Load.C.cmdsize < SegmentLoadSize) {
312+
EC = object_error::macho_load_segment_too_small;
313+
return;
314+
}
315+
auto NumSectionsOrErr = getSegmentLoadCommandNumSections(this, Load);
316+
if (!NumSectionsOrErr) {
317+
EC = NumSectionsOrErr.getError();
318+
return;
319+
}
320+
for (unsigned J = 0; J < NumSectionsOrErr.get(); ++J) {
317321
const char *Sec = getSectionPtr(this, Load, J);
318322
Sections.push_back(Sec);
319323
}

‎llvm/test/Object/macho-invalid.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-too-small-segment
1515
RUN: | FileCheck -check-prefix SMALL-SEGLOADC-SIZE %s
1616
RUN: not llvm-objdump -private-headers %p/Inputs/macho64-invalid-too-small-segment-load-command 2>&1 \
1717
RUN: | FileCheck -check-prefix SMALL-SEGLOADC-SIZE %s
18-
SMALL-SEGLOADC-SIZE: Segment load command size is too small
18+
SMALL-SEGLOADC-SIZE: Mach-O segment load command size is too small
1919

2020
RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-no-size-for-sections 2>&1 \
2121
RUN: | FileCheck -check-prefix TOO-MANY-SECTS %s
2222
RUN: not llvm-objdump -private-headers %p/Inputs/macho64-invalid-no-size-for-sections 2>&1 \
2323
RUN: | FileCheck -check-prefix TOO-MANY-SECTS %s
24-
TOO-MANY-SECTS: Number of sections too large for size of load command
24+
TOO-MANY-SECTS: Mach-O segment load command contains too many sections
2525

2626
RUN: not llvm-objdump -t %p/Inputs/macho-invalid-bad-symbol-index 2>&1 \
2727
RUN: | FileCheck -check-prefix BAD-SYMBOL %s

0 commit comments

Comments
 (0)
Please sign in to comment.