From de5a94a6b4d1574fea0f252e65408343338ba664 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Thu, 4 Jun 2015 19:57:46 +0000 Subject: [Object, MachO] Don't crash on invalid MachO load commands. Summary: Currently all load commands are parsed in MachOObjectFile constructor. If the next load command cannot be parsed, or if command size is too small, properly report it through the error code and fail to construct the object, instead of crashing the program. Test Plan: regression test suite Reviewers: rafael, filcab Subscribers: llvm-commits llvm-svn: 239080 --- llvm/lib/Object/MachOObjectFile.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'llvm/lib/Object/MachOObjectFile.cpp') diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index c1d1383..3262c6c 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -194,24 +194,27 @@ static uint32_t getSectionFlags(const MachOObjectFile *O, return Sect.flags; } -static MachOObjectFile::LoadCommandInfo +static ErrorOr getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr) { + auto CmdOrErr = getStructOrErr(Obj, Ptr); + if (!CmdOrErr) + return CmdOrErr.getError(); + if (CmdOrErr->cmdsize < 8) + return object_error::macho_small_load_command; MachOObjectFile::LoadCommandInfo Load; Load.Ptr = Ptr; - Load.C = getStruct(Obj, Load.Ptr); - if (Load.C.cmdsize < 8) - report_fatal_error("Load command with size < 8 bytes."); + Load.C = CmdOrErr.get(); return Load; } -static MachOObjectFile::LoadCommandInfo +static ErrorOr getFirstLoadCommandInfo(const MachOObjectFile *Obj) { unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header); return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize)); } -static MachOObjectFile::LoadCommandInfo +static ErrorOr getNextLoadCommandInfo(const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &L) { return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize); @@ -251,7 +254,12 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, MachO::LoadCommandType SegmentLoadType = is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT; - LoadCommandInfo Load = getFirstLoadCommandInfo(this); + auto LoadOrErr = getFirstLoadCommandInfo(this); + if (!LoadOrErr) { + EC = LoadOrErr.getError(); + return; + } + LoadCommandInfo Load = LoadOrErr.get(); for (unsigned I = 0; I < LoadCommandCount; ++I) { LoadCommands.push_back(Load); if (Load.C.cmd == MachO::LC_SYMTAB) { @@ -318,8 +326,14 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) { Libraries.push_back(Load.Ptr); } - if (I < LoadCommandCount - 1) - Load = getNextLoadCommandInfo(this, Load); + if (I < LoadCommandCount - 1) { + auto LoadOrErr = getNextLoadCommandInfo(this, Load); + if (!LoadOrErr) { + EC = LoadOrErr.getError(); + return; + } + Load = LoadOrErr.get(); + } } assert(LoadCommands.size() == LoadCommandCount); } -- cgit v1.1