[llvm] r239081 - [Object, MachO] Don't crash on invalid MachO segment load commands.

Alexey Samsonov vonosmas at gmail.com
Thu Jun 4 13:08:52 PDT 2015


Author: samsonov
Date: Thu Jun  4 15:08:52 2015
New Revision: 239081

URL: http://llvm.org/viewvc/llvm-project?rev=239081&view=rev
Log:
[Object, MachO] Don't crash on invalid MachO segment load commands.

Summary:
Properly report the error in segment load commands from MachOObjectFile
constructor instead of crashing the program.

Adjust the test case accordingly.

Test Plan: regression test suite

Reviewers: rafael, filcab

Subscribers: llvm-commits

Modified:
    llvm/trunk/include/llvm/Object/Error.h
    llvm/trunk/lib/Object/Error.cpp
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/test/Object/macho-invalid.test

Modified: llvm/trunk/include/llvm/Object/Error.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Error.h?rev=239081&r1=239080&r2=239081&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Error.h (original)
+++ llvm/trunk/include/llvm/Object/Error.h Thu Jun  4 15:08:52 2015
@@ -29,6 +29,8 @@ enum class object_error {
   unexpected_eof,
   bitcode_section_not_found,
   macho_small_load_command,
+  macho_load_segment_too_many_sections,
+  macho_load_segment_too_small,
 };
 
 inline std::error_code make_error_code(object_error e) {

Modified: llvm/trunk/lib/Object/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Error.cpp?rev=239081&r1=239080&r2=239081&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Error.cpp (original)
+++ llvm/trunk/lib/Object/Error.cpp Thu Jun  4 15:08:52 2015
@@ -46,6 +46,10 @@ std::string _object_error_category::mess
     return "Bitcode section not found in object file";
   case object_error::macho_small_load_command:
     return "Mach-O load command with size < 8 bytes";
+  case object_error::macho_load_segment_too_many_sections:
+    return "Mach-O segment load command contains too many sections";
+  case object_error::macho_load_segment_too_small:
+    return "Mach-O segment load command size is too small";
   }
   llvm_unreachable("An enumerator of object_error does not have a message "
                    "defined.");

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=239081&r1=239080&r2=239081&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Thu Jun  4 15:08:52 2015
@@ -66,17 +66,16 @@ static ErrorOr<T> getStructOrErr(const M
 }
 
 template <typename SegmentCmd>
-static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S,
-                                                 uint32_t Cmdsize) {
+static ErrorOr<uint32_t> getSegmentLoadCommandNumSections(const SegmentCmd &S,
+                                                          uint32_t Cmdsize) {
   const unsigned SectionSize = sizeof(SegmentCmd);
   if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
       S.nsects * SectionSize > Cmdsize - sizeof(S))
-    report_fatal_error(
-        "Number of sections too large for size of load command.");
+    return object_error::macho_load_segment_too_many_sections;
   return S.nsects;
 }
 
-static uint32_t
+static ErrorOr<uint32_t>
 getSegmentLoadCommandNumSections(const MachOObjectFile *O,
                                  const MachOObjectFile::LoadCommandInfo &L) {
   if (O->is64Bit())
@@ -306,14 +305,19 @@ MachOObjectFile::MachOObjectFile(MemoryB
       }
       UuidLoadCmd = Load.Ptr;
     } else if (Load.C.cmd == SegmentLoadType) {
-      const unsigned SegmentLoadSize = this->is64Bit()
+      const unsigned SegmentLoadSize = is64Bit()
                                            ? sizeof(MachO::segment_command_64)
                                            : sizeof(MachO::segment_command);
-      if (Load.C.cmdsize < SegmentLoadSize)
-        report_fatal_error("Segment load command size is too small.");
-
-      uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
-      for (unsigned J = 0; J < NumSections; ++J) {
+      if (Load.C.cmdsize < SegmentLoadSize) {
+        EC = object_error::macho_load_segment_too_small;
+        return;
+      }
+      auto NumSectionsOrErr = getSegmentLoadCommandNumSections(this, Load);
+      if (!NumSectionsOrErr) {
+        EC = NumSectionsOrErr.getError();
+        return;
+      }
+      for (unsigned J = 0; J < NumSectionsOrErr.get(); ++J) {
         const char *Sec = getSectionPtr(this, Load, J);
         Sections.push_back(Sec);
       }

Modified: llvm/trunk/test/Object/macho-invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/macho-invalid.test?rev=239081&r1=239080&r2=239081&view=diff
==============================================================================
--- llvm/trunk/test/Object/macho-invalid.test (original)
+++ llvm/trunk/test/Object/macho-invalid.test Thu Jun  4 15:08:52 2015
@@ -15,13 +15,13 @@ RUN: not llvm-objdump -private-headers %
 RUN:      | FileCheck -check-prefix SMALL-SEGLOADC-SIZE %s
 RUN: not llvm-objdump -private-headers %p/Inputs/macho64-invalid-too-small-segment-load-command 2>&1 \
 RUN:      | FileCheck -check-prefix SMALL-SEGLOADC-SIZE %s
-SMALL-SEGLOADC-SIZE: Segment load command size is too small
+SMALL-SEGLOADC-SIZE: Mach-O segment load command size is too small
 
 RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-no-size-for-sections 2>&1 \
 RUN:      | FileCheck -check-prefix TOO-MANY-SECTS %s
 RUN: not llvm-objdump -private-headers %p/Inputs/macho64-invalid-no-size-for-sections 2>&1 \
 RUN:      | FileCheck -check-prefix TOO-MANY-SECTS %s
-TOO-MANY-SECTS: Number of sections too large for size of load command
+TOO-MANY-SECTS: Mach-O segment load command contains too many sections
 
 RUN: not llvm-objdump -t %p/Inputs/macho-invalid-bad-symbol-index 2>&1 \
 RUN:      | FileCheck -check-prefix BAD-SYMBOL %s





More information about the llvm-commits mailing list