Browse Source

Add the first of what will be a long line of additional error checks for invalid Mach-O files.

This is where an LC_SEGMENT load command has a fileoff field that
extends past the end of the file.

Also fix llvm-nm and llvm-size to remove the errorToErrorCode() call so error messages are printed.
And needed to update a few test cases now that they do print the error messages just a
bit differently.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277845 91177308-0d34-0410-b5e6-96231b3b80d8
Kevin Enderby 9 years ago
parent
commit
cedb0b6b7e

+ 5 - 0
lib/Object/MachOObjectFile.cpp

@@ -241,6 +241,11 @@ static Error parseSegmentLoadCommand(
       const char *Sec = getSectionPtr(Obj, Load, J);
       Sections.push_back(Sec);
     }
+    uint64_t FileSize = Obj->getData().size();
+    if (S.fileoff > FileSize)
+      return malformedError("load command " + Twine(LoadCommandIndex) +
+                            " fileoff field in " + CmdName + 
+                            " extends past the end of the file");
     IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
   } else
     return SegOrErr.takeError();

BIN
test/Object/Inputs/macho-invalid-segment-fileoff


+ 9 - 0
test/Object/macho-invalid.test

@@ -103,3 +103,12 @@ INVALID-FAT: truncated or malformed fat file (fat_arch_64 structs would extend p
 
 RUN: not llvm-objdump -macho -private-headers -arch all %p/Inputs/macho-invalid-fat.obj.elf-x86_64 2>&1 | FileCheck -check-prefix INVALID-FAT-ELF %s
 INVALID-FAT-ELF: Mach-O universal file: {{.*}}/macho-invalid-fat.obj.elf-x86_64 for architecture x86_64 is not a Mach-O file or an archive file
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-segment-fileoff 2>&1 | FileCheck -check-prefix INVALID-SEGMENT-FILEOFF %s
+INVALID-SEGMENT-FILEOFF: macho-invalid-segment-fileoff': truncated or malformed object (load command 0 fileoff field in LC_SEGMENT extends past the end of the file)
+
+RUN: not llvm-nm %p/Inputs/macho-invalid-segment-fileoff 2>&1 | FileCheck -check-prefix INVALID-SEGMENT-FILEOFF-NM %s
+INVALID-SEGMENT-FILEOFF-NM: macho-invalid-segment-fileoff truncated or malformed object (load command 0 fileoff field in LC_SEGMENT extends past the end of the file)
+
+RUN: not llvm-size %p/Inputs/macho-invalid-segment-fileoff 2>&1 | FileCheck -check-prefix INVALID-SEGMENT-FILEOFF-SIZE %s
+INVALID-SEGMENT-FILEOFF-SIZE: macho-invalid-segment-fileoff truncated or malformed object (load command 0 fileoff field in LC_SEGMENT extends past the end of the file)

+ 1 - 1
test/tools/llvm-nm/invalid-input.test

@@ -1,2 +1,2 @@
 RUN: not llvm-nm %s 2>&1 | FileCheck %s -check-prefix=UNKNOWN_FILE_TYPE
-UNKNOWN_FILE_TYPE: {{.*}}invalid-input.test: The file was not recognized as a valid object file
+UNKNOWN_FILE_TYPE: {{.*}}invalid-input.test The file was not recognized as a valid object file

+ 1 - 1
test/tools/llvm-size/basic.test

@@ -1,2 +1,2 @@
 RUN: not llvm-size %t.blah 2>&1 | FileCheck --check-prefix=ENOENT %s
-ENOENT: {{.*}}llvm-size{{(\.EXE|\.exe)?}}: error reading file: {{[Nn]}}o such file or directory
+ENOENT: {{.*}}llvm-size{{(\.EXE|\.exe)?}}: {{.*}}basic.test.tmp.blah {{[Nn]}}o such file or directory

+ 1 - 1
tools/llvm-nm/llvm-nm.cpp

@@ -1085,7 +1085,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
   Expected<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
       BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context);
   if (!BinaryOrErr) {
-    error(errorToErrorCode(BinaryOrErr.takeError()), Filename);
+    error(BinaryOrErr.takeError(), Filename);
     return;
   }
   Binary &Bin = *BinaryOrErr.get();

+ 1 - 1
tools/llvm-size/llvm-size.cpp

@@ -521,7 +521,7 @@ static void printFileSectionSizes(StringRef file) {
   // Attempt to open the binary.
   Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
   if (!BinaryOrErr) {
-    error(errorToErrorCode(BinaryOrErr.takeError()));
+    error(BinaryOrErr.takeError(), file);
     return;
   }
   Binary &Bin = *BinaryOrErr.get().getBinary();