]> granicus.if.org Git - llvm/commitdiff
Produce another specific error message for a malformed Mach-O file when a load
authorKevin Enderby <enderby@apple.com>
Tue, 3 May 2016 17:16:08 +0000 (17:16 +0000)
committerKevin Enderby <enderby@apple.com>
Tue, 3 May 2016 17:16:08 +0000 (17:16 +0000)
command other than the first one is past the end of the load commands.

This is like the test case in test/Object/macho-invalid.test for
macho64-invalid-incomplete-load-command but it is the second load command
that is past the end of all the load commands instead of the first.

The code in the constructor for MachOObjectFile that loops over the load
commands used getNextLoadCommandInfo() which was not producing
a good error message.  So that was fixed and a test case was added.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268403 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Object/MachOObjectFile.cpp
test/Object/Inputs/macho64-invalid-incomplete-load-command.1 [new file with mode: 0644]
test/Object/macho-invalid.test

index 2240dc8b04a58c749b153fbc9098c3809e0f11f2..744603ae730c5a665b4a3e06a3cc13a7429241ba 100644 (file)
@@ -199,8 +199,16 @@ getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
 }
 
 static Expected<MachOObjectFile::LoadCommandInfo>
-getNextLoadCommandInfo(const MachOObjectFile *Obj,
+getNextLoadCommandInfo(const MachOObjectFile *Obj, uint32_t LoadCommandIndex,
                        const MachOObjectFile::LoadCommandInfo &L) {
+  unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
+                                       : sizeof(MachO::mach_header);
+  if (L.Ptr + L.C.cmdsize + sizeof(MachOObjectFile::LoadCommandInfo) >
+      Obj->getData().data() + HeaderSize + Obj->getHeader().sizeofcmds)
+    return malformedError(*Obj, Twine("truncated or malformed object "
+                          "(load command ") + Twine(LoadCommandIndex + 1) +
+                          Twine(" extends past the end all load commands in the "
+                          "file)"));
   return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
 }
 
@@ -361,7 +369,7 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
       Libraries.push_back(Load.Ptr);
     }
     if (I < LoadCommandCount - 1) {
-      if (auto LoadOrErr = getNextLoadCommandInfo(this, Load))
+      if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
         Load = *LoadOrErr;
       else {
         Err = LoadOrErr.takeError();
diff --git a/test/Object/Inputs/macho64-invalid-incomplete-load-command.1 b/test/Object/Inputs/macho64-invalid-incomplete-load-command.1
new file mode 100644 (file)
index 0000000..f7b0789
Binary files /dev/null and b/test/Object/Inputs/macho64-invalid-incomplete-load-command.1 differ
index 038f5a840f98a0d2c1a86e82a88c522977ccced4..92b18079b5defeea57f57ebf1f0d9163f4b7b6ec 100644 (file)
@@ -9,6 +9,10 @@ RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho64-invalid-incomple
 RUN:      | FileCheck -check-prefix INCOMPLETE-LOADC %s
 INCOMPLETE-LOADC: truncated or malformed object (load command 0 extends past the end all load commands in the file)
 
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho64-invalid-incomplete-load-command.1 2>&1 \
+RUN:      | FileCheck -check-prefix INCOMPLETE-LOADC-1 %s
+INCOMPLETE-LOADC-1: truncated or malformed object (load command 1 extends past the end all load commands in the file)
+
 RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-too-small-load-command 2>&1 \
 RUN:      | FileCheck -check-prefix SMALL-LOADC-SIZE %s
 RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho64-invalid-too-small-load-command 2>&1 \