nother additional error check for an invalid Mach-O file

when contained in a Mach-O universal file and the
cputypes in both headers don’t match.

llvm-svn: 285026
This commit is contained in:
Kevin Enderby
2016-10-24 21:15:11 +00:00
parent d8ec09c74f
commit 79d6c63f61
6 changed files with 44 additions and 14 deletions

View File

@@ -914,18 +914,22 @@ static Error checkTwoLevelHintsCommand(const MachOObjectFile *Obj,
Expected<std::unique_ptr<MachOObjectFile>>
MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
bool Is64Bits) {
bool Is64Bits, uint32_t UniversalCputype,
uint32_t UniversalIndex) {
Error Err;
std::unique_ptr<MachOObjectFile> Obj(
new MachOObjectFile(std::move(Object), IsLittleEndian,
Is64Bits, Err));
Is64Bits, Err, UniversalCputype,
UniversalIndex));
if (Err)
return std::move(Err);
return std::move(Obj);
}
MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
bool Is64bits, Error &Err)
bool Is64bits, Error &Err,
uint32_t UniversalCputype,
uint32_t UniversalIndex)
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
@@ -933,12 +937,15 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
HasPageZeroSegment(false) {
ErrorAsOutParameter ErrAsOutParam(&Err);
uint64_t SizeOfHeaders;
uint32_t cputype;
if (is64Bit()) {
parseHeader(this, Header64, Err);
SizeOfHeaders = sizeof(MachO::mach_header_64);
cputype = Header64.cputype;
} else {
parseHeader(this, Header, Err);
SizeOfHeaders = sizeof(MachO::mach_header);
cputype = Header.cputype;
}
if (Err)
return;
@@ -947,6 +954,12 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
Err = malformedError("load commands extend past the end of the file");
return;
}
if (UniversalCputype != 0 && cputype != UniversalCputype) {
Err = malformedError("universal header architecture: " +
Twine(UniversalIndex) + "'s cputype does not match "
"object file's mach header");
return;
}
uint32_t LoadCommandCount = getHeader().ncmds;
LoadCommandInfo Load;
@@ -3281,16 +3294,22 @@ bool MachOObjectFile::isRelocatableObject() const {
}
Expected<std::unique_ptr<MachOObjectFile>>
ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
uint32_t UniversalCputype,
uint32_t UniversalIndex) {
StringRef Magic = Buffer.getBuffer().slice(0, 4);
if (Magic == "\xFE\xED\xFA\xCE")
return MachOObjectFile::create(Buffer, false, false);
return MachOObjectFile::create(Buffer, false, false,
UniversalCputype, UniversalIndex);
if (Magic == "\xCE\xFA\xED\xFE")
return MachOObjectFile::create(Buffer, true, false);
return MachOObjectFile::create(Buffer, true, false,
UniversalCputype, UniversalIndex);
if (Magic == "\xFE\xED\xFA\xCF")
return MachOObjectFile::create(Buffer, false, true);
return MachOObjectFile::create(Buffer, false, true,
UniversalCputype, UniversalIndex);
if (Magic == "\xCF\xFA\xED\xFE")
return MachOObjectFile::create(Buffer, true, true);
return MachOObjectFile::create(Buffer, true, true,
UniversalCputype, UniversalIndex);
return make_error<GenericBinaryError>("Unrecognized MachO magic number",
object_error::invalid_file_type);
}