[llvm] r284769 - Another additional error check for invalid Mach-O files for the

Kevin Enderby via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 20 13:10:30 PDT 2016


Author: enderby
Date: Thu Oct 20 15:10:30 2016
New Revision: 284769

URL: http://llvm.org/viewvc/llvm-project?rev=284769&view=rev
Log:
Another additional error check for invalid Mach-O files for the
load commands that use the MachO::twolevel_hints_command type
which includes only the LC_TWOLEVEL_HINTS load command.

This is not used in llvm libObject code or in llvm tool code.  But
does appear in one of the binary test files.  While this load command is
obsolete it is easier to add code for it in libObject than edit or change
the binary test case.

Added:
    llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-bad-size   (with props)
    llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-more-than-one   (with props)
    llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-offset   (with props)
    llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-offset-nhints   (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=284769&r1=284768&r2=284769&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Thu Oct 20 15:10:30 2016
@@ -883,6 +883,35 @@ static Error checkThreadCommand(const Ma
   return Error::success();
 }
 
+static Error checkTwoLevelHintsCommand(const MachOObjectFile *Obj,
+                                       const MachOObjectFile::LoadCommandInfo
+                                         &Load,
+                                       uint32_t LoadCommandIndex,
+                                       const char **LoadCmd) {
+  if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command))
+    return malformedError("load command " + Twine(LoadCommandIndex) +
+                          " LC_TWOLEVEL_HINTS has incorrect cmdsize");
+  if (*LoadCmd != nullptr)
+    return malformedError("more than one LC_TWOLEVEL_HINTS command");
+  MachO::twolevel_hints_command Hints =
+    getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr);
+  uint64_t FileSize = Obj->getData().size();
+  if (Hints.offset > FileSize)
+    return malformedError("offset field of LC_TWOLEVEL_HINTS command " +
+                          Twine(LoadCommandIndex) + " extends past the end of "
+                          "the file");
+  uint64_t BigSize = Hints.nhints;
+  BigSize *= Hints.nhints * sizeof(MachO::twolevel_hint);
+  BigSize += Hints.offset;
+  if (BigSize > FileSize)
+    return malformedError("offset field plus nhints times sizeof(struct "
+                          "twolevel_hint) field of LC_TWOLEVEL_HINTS command " +
+                          Twine(LoadCommandIndex) + " extends past the end of "
+                          "the file");
+  *LoadCmd = Load.Ptr;
+  return Error::success();
+}
+
 Expected<std::unique_ptr<MachOObjectFile>>
 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
                         bool Is64Bits) {
@@ -941,6 +970,7 @@ MachOObjectFile::MachOObjectFile(MemoryB
   const char *EncryptLoadCmd = nullptr;
   const char *RoutinesLoadCmd = nullptr;
   const char *UnixThreadLoadCmd = nullptr;
+  const char *TwoLevelHintsLoadCmd = nullptr;
   for (unsigned I = 0; I < LoadCommandCount; ++I) {
     if (is64Bit()) {
       if (Load.C.cmdsize % 8 != 0) {
@@ -1207,6 +1237,10 @@ MachOObjectFile::MachOObjectFile(MemoryB
     } else if (Load.C.cmd == MachO::LC_THREAD) {
       if ((Err = checkThreadCommand(this, Load, I, "LC_THREAD")))
         return;
+    } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) {
+       if ((Err = checkTwoLevelHintsCommand(this, Load, I,
+                                            &TwoLevelHintsLoadCmd)))
+         return;
     }
     if (I < LoadCommandCount - 1) {
       if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))

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

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-bad-size
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-more-than-one
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-more-than-one?rev=284769&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-more-than-one
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

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

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

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

Propchange: llvm/trunk/test/Object/Inputs/macho-invalid-twolevelhints-offset-nhints
------------------------------------------------------------------------------
    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=284769&r1=284768&r2=284769&view=diff
==============================================================================
--- llvm/trunk/test/Object/macho-invalid.test (original)
+++ llvm/trunk/test/Object/macho-invalid.test Thu Oct 20 15:10:30 2016
@@ -394,3 +394,15 @@ INVALID-THREAD-UNKNOWN-CPUTYPE: macho-in
 
 RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-unixthread-more-than-one 2>&1 | FileCheck -check-prefix INVALID-UNIXTHREAD-MORE-THAN-ONE %s
 INVALID-UNIXTHREAD-MORE-THAN-ONE: macho-invalid-unixthread-more-than-one': truncated or malformed object (more than one LC_UNIXTHREAD command)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-twolevelhints-bad-size 2>&1 | FileCheck -check-prefix INVALID-TWOLEVELHINTS-BAD-SIZE %s
+INVALID-TWOLEVELHINTS-BAD-SIZE: macho-invalid-twolevelhints-bad-size': truncated or malformed object (load command 0 LC_TWOLEVEL_HINTS has incorrect cmdsize)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-twolevelhints-more-than-one 2>&1 | FileCheck -check-prefix INVALID-TWOLEVELHINTS-MORE-THAN-ONE %s
+INVALID-TWOLEVELHINTS-MORE-THAN-ONE: macho-invalid-twolevelhints-more-than-one': truncated or malformed object (more than one LC_TWOLEVEL_HINTS command)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-twolevelhints-offset 2>&1 | FileCheck -check-prefix INVALID-TWOLEVELHINTS-OFFSET %s
+INVALID-TWOLEVELHINTS-OFFSET: macho-invalid-twolevelhints-offset': truncated or malformed object (offset field of LC_TWOLEVEL_HINTS command 0 extends past the end of the file)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-twolevelhints-offset-nhints 2>&1 | FileCheck -check-prefix INVALID-TWOLEVELHINTS-OFFSET-HNINTS %s
+INVALID-TWOLEVELHINTS-OFFSET-HNINTS: macho-invalid-twolevelhints-offset-nhints': truncated or malformed object (offset field plus nhints times sizeof(struct twolevel_hint) field of LC_TWOLEVEL_HINTS command 0 extends past the end of the file)




More information about the llvm-commits mailing list