[llvm] r284431 - Next set of additional error checks for invalid Mach-O files for the

Kevin Enderby via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 17 15:09:25 PDT 2016


Author: enderby
Date: Mon Oct 17 17:09:25 2016
New Revision: 284431

URL: http://llvm.org/viewvc/llvm-project?rev=284431&view=rev
Log:
Next set of additional error checks for invalid Mach-O files for the
load commands that use the MachO::sub_framework_command,
MachO::sub_umbrella_command, MachO::sub_library_command
and MachO::sub_client_command types but are not used in llvm
libObject code but used in llvm tool code.

This includes the LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA,
LC_SUB_LIBRARY and LC_SUB_CLIENT load commands.

Added:
    llvm/trunk/test/Object/Inputs/macho-invalid-subclient-name_toobig   (with props)
    llvm/trunk/test/Object/Inputs/macho-invalid-subframe-small   (with props)
    llvm/trunk/test/Object/Inputs/macho-invalid-sublibrary-name_offset-toobig   (with props)
    llvm/trunk/test/Object/Inputs/macho-invalid-subumbrella-offset-small   (with props)
Modified:
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/test/Object/macho-invalid.test

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=284431&r1=284430&r2=284431&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Mon Oct 17 17:09:25 2016
@@ -755,6 +755,33 @@ static Error checkLinkerOptCommand(const
   return Error::success();
 }
 
+static Error checkSubCommand(const MachOObjectFile *Obj,
+                             const MachOObjectFile::LoadCommandInfo &Load,
+                             uint32_t LoadCommandIndex, const char *CmdName,
+                             size_t SizeOfCmd, const char *CmdStructName,
+                             uint32_t PathOffset, const char *PathFieldName) {
+  if (PathOffset < SizeOfCmd)
+    return malformedError("load command " + Twine(LoadCommandIndex) + " " +
+                          CmdName + " " + PathFieldName + ".offset field too "
+                          "small, not past the end of the " + CmdStructName);
+  if (PathOffset >= Load.C.cmdsize)
+    return malformedError("load command " + Twine(LoadCommandIndex) + " " +
+                          CmdName + " " + PathFieldName + ".offset field "
+                          "extends past the end of the load command");
+  // Make sure there is a null between the starting offset of the path and
+  // the end of the load command.
+  uint32_t i;
+  const char *P = (const char *)Load.Ptr;
+  for (i = PathOffset; i < Load.C.cmdsize; i++)
+    if (P[i] == '\0')
+      break;
+  if (i >= Load.C.cmdsize)
+    return malformedError("load command " + Twine(LoadCommandIndex) + " " +
+                          CmdName + " " + PathFieldName + " name extends past "
+                          "the end of the load command");
+  return Error::success();
+}
+
 Expected<std::unique_ptr<MachOObjectFile>>
 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
                         bool Is64Bits) {
@@ -986,6 +1013,57 @@ MachOObjectFile::MachOObjectFile(MemoryB
     } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
       if ((Err = checkLinkerOptCommand(this, Load, I)))
         return;
+    } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) {
+      if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) {
+        Err =  malformedError("load command " + Twine(I) +
+                              " LC_SUB_FRAMEWORK cmdsize too small");
+        return;
+      }
+      MachO::sub_framework_command S =
+        getStruct<MachO::sub_framework_command>(this, Load.Ptr);
+      if ((Err = checkSubCommand(this, Load, I, "LC_SUB_FRAMEWORK",
+                                 sizeof(MachO::sub_framework_command),
+                                 "sub_framework_command", S.umbrella,
+                                 "umbrella")))
+        return;
+    } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) {
+      if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) {
+        Err =  malformedError("load command " + Twine(I) +
+                              " LC_SUB_UMBRELLA cmdsize too small");
+        return;
+      }
+      MachO::sub_umbrella_command S =
+        getStruct<MachO::sub_umbrella_command>(this, Load.Ptr);
+      if ((Err = checkSubCommand(this, Load, I, "LC_SUB_UMBRELLA",
+                                 sizeof(MachO::sub_umbrella_command),
+                                 "sub_umbrella_command", S.sub_umbrella,
+                                 "sub_umbrella")))
+        return;
+    } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) {
+      if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) {
+        Err =  malformedError("load command " + Twine(I) +
+                              " LC_SUB_LIBRARY cmdsize too small");
+        return;
+      }
+      MachO::sub_library_command S =
+        getStruct<MachO::sub_library_command>(this, Load.Ptr);
+      if ((Err = checkSubCommand(this, Load, I, "LC_SUB_LIBRARY",
+                                 sizeof(MachO::sub_library_command),
+                                 "sub_library_command", S.sub_library,
+                                 "sub_library")))
+        return;
+    } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) {
+      if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) {
+        Err =  malformedError("load command " + Twine(I) +
+                              " LC_SUB_CLIENT cmdsize too small");
+        return;
+      }
+      MachO::sub_client_command S =
+        getStruct<MachO::sub_client_command>(this, Load.Ptr);
+      if ((Err = checkSubCommand(this, Load, I, "LC_SUB_CLIENT",
+                                 sizeof(MachO::sub_client_command),
+                                 "sub_client_command", S.client, "client")))
+        return;
     }
     if (I < LoadCommandCount - 1) {
       if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))

Added: llvm/trunk/test/Object/Inputs/macho-invalid-subclient-name_toobig
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-invalid-subclient-name_toobig?rev=284431&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-subclient-name_toobig
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/Inputs/macho-invalid-subframe-small
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-invalid-subframe-small?rev=284431&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-subframe-small
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/Inputs/macho-invalid-sublibrary-name_offset-toobig
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-invalid-sublibrary-name_offset-toobig?rev=284431&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-sublibrary-name_offset-toobig
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/Inputs/macho-invalid-subumbrella-offset-small
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-invalid-subumbrella-offset-small?rev=284431&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-subumbrella-offset-small
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: llvm/trunk/test/Object/macho-invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/macho-invalid.test?rev=284431&r1=284430&r2=284431&view=diff
==============================================================================
--- llvm/trunk/test/Object/macho-invalid.test (original)
+++ llvm/trunk/test/Object/macho-invalid.test Mon Oct 17 17:09:25 2016
@@ -355,3 +355,15 @@ INVALID-LINKOPT-BAD-SIZE: macho-invalid-
 
 RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-linkopt-bad-count 2>&1 | FileCheck -check-prefix INVALID-LINKOPT-BAD-COUNT %s
 INVALID-LINKOPT-BAD-COUNT: macho-invalid-linkopt-bad-count': truncated or malformed object (load command 0 LC_LINKER_OPTION string count 3 does not match number of strings)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-subframe-small 2>&1 | FileCheck -check-prefix INVALID-SUBFRAME-SMALL %s
+INVALID-SUBFRAME-SMALL: macho-invalid-subframe-small': truncated or malformed object (load command 0 LC_SUB_FRAMEWORK cmdsize too small)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-subumbrella-offset-small 2>&1 | FileCheck -check-prefix INVALID-SUBUMBRELLA-OFFSET-SMALL %s
+INVALID-SUBUMBRELLA-OFFSET-SMALL: macho-invalid-subumbrella-offset-small': truncated or malformed object (load command 0 LC_SUB_UMBRELLA sub_umbrella.offset field too small, not past the end of the sub_umbrella_command)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-sublibrary-name_offset-toobig 2>&1 | FileCheck -check-prefix INVALID-SUBLIB-NAME_OFFSET-TOOBIG %s
+INVALID-SUBLIB-NAME_OFFSET-TOOBIG: macho-invalid-sublibrary-name_offset-toobig': truncated or malformed object (load command 0 LC_SUB_LIBRARY sub_library.offset field extends past the end of the load command)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-subclient-name_toobig 2>&1 | FileCheck -check-prefix INVALID-SUBCLIENT-NAME-TOOBIG %s
+INVALID-SUBCLIENT-NAME-TOOBIG: macho-invalid-subclient-name_toobig': truncated or malformed object (load command 0 LC_SUB_CLIENT client name extends past the end of the load command)




More information about the llvm-commits mailing list