Fix a bug in llvm-objdump’s printing of Objective-C meta data

from malformed Mach-O files that caused a crash because of a
section header had a size that extended past the end of the file.

rdar://22983603

llvm-svn: 249768
This commit is contained in:
Kevin Enderby 2015-10-08 22:50:55 +00:00
parent 6eeaff169d
commit 46e642f8c5
4 changed files with 34 additions and 3 deletions

View File

@ -483,9 +483,32 @@ uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const {
}
uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
if (is64Bit())
return getSection64(Sec).size;
return getSection(Sec).size;
// In the case if a malformed Mach-O file where the section offset is past
// the end of the file or some part of the section size is past the end of
// the file return a size of zero or a size that covers the rest of the file
// but does not extend past the end of the file.
uint32_t SectOffset, SectType;
uint64_t SectSize;
if (is64Bit()) {
MachO::section_64 Sect = getSection64(Sec);
SectOffset = Sect.offset;
SectSize = Sect.size;
SectType = Sect.flags & MachO::SECTION_TYPE;
} else {
MachO::section Sect = getSection(Sec);
SectOffset = Sect.offset;
SectSize = Sect.size;
SectType = Sect.flags & MachO::SECTION_TYPE;
}
if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL)
return SectSize;
uint64_t FileSize = getData().size();
if (SectOffset > FileSize)
return 0;
if (FileSize - SectOffset < SectSize)
return FileSize - SectOffset;
return SectSize;
}
std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,

View File

@ -18,3 +18,9 @@
# RUN: | FileCheck -check-prefix=m0010 %s
# m0010: 00000000000010e0 0x10e8 _OBJC_CLASS_
# RUN: llvm-objdump -macho -objc-meta-data \
# RUN: %p/Inputs/malformed-machos/mem-crup-0040.macho \
# RUN: | FileCheck -check-prefix=m0040 %s
# m0040: 00000000000010a0 0xf39 -[tiny_dylib init]

View File

@ -2340,6 +2340,8 @@ static const char *get_pointer_64(uint64_t Address, uint32_t &offset,
for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
if (SectSize == 0)
continue;
if (objc_only) {
StringRef SectName;
((*(info->Sections))[SectIdx]).getName(SectName);