<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 13, 2016 at 2:17 PM, Kevin Enderby via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: enderby<br>
Date: Wed Apr 13 16:17:58 2016<br>
New Revision: 266248<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=266248&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=266248&view=rev</a><br>
Log:<br>
Start to add real error messages for malformed Mach-O files.<br>
And update the existing test cases in test/Object/macho-invalid.test<br>
to use llvm-objdump with the -macho option to produce these<br>
error messages and stop producing the generic "Invalid data<br>
was encountered while parsing the file" message.<br>
<br>
Working from the beginning of the file, if the mach header is too large for<br>
the size of the file and then if the load commands that follow extend past<br>
the end of the file these two errors now generate correct error messages.<br>
<br>
Both of these have existing test cases in test/Object/macho-invalid.test .<br>
<br>
But the first with macho-invalid-header it will never trigger the error message<br>
"mach header extends past the end of the file" using any of the llvm tools as<br>
they all use identify_magic() which rejects files with the correct magic number<br>
that are too small in size.  So I tested this by hacking that code and seeing the<br>
error message down in parseHeader() really does happen.  So in case there<br>
is ever code in llvm that directly calls createMachOObjectFile() this error<br>
message will be correctly produced.<br>
<br>
The second error message of "load commands extends past the end of the file"<br>
is triggered by a number of existing tests cases in test/Object/macho-invalid.test .<br>
Also other tests trigger different error messages now like "ilocalsym plus<br>
nlocalsym in LC_DYSYMTAB load command extends past the end of the<br>
symbol table".<br>
<br>
There are two existing test cases that still get the "Invalid data was encountered ..."<br>
error messages that I will tackle next.  But they will involve a bit of pluming an<br>
Expect<...> up through the call stack and I want to do those as separate changes.<br>
<br>
FYI, for those test cases that were trying to test specific errors that now get<br>
different errors I’ll fix those in follow on changes and create new test cases<br>
for those so they test the error they were meant to test.<br>
<br>
Modified:<br>
    llvm/trunk/lib/Object/MachOObjectFile.cpp<br>
    llvm/trunk/test/Object/macho-invalid.test<br>
<br>
Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=266248&r1=266247&r2=266248&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=266248&r1=266247&r2=266248&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)<br>
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Wed Apr 13 16:17:58 2016<br>
@@ -208,6 +208,11 @@ getNextLoadCommandInfo(const MachOObject<br>
 template <typename T><br>
 static void parseHeader(const MachOObjectFile *Obj, T &Header,<br>
                         Error &Err) {<br>
+  if (sizeof(T) > Obj->getData().size()) {<br>
+    Err = malformedError(*Obj, "truncated or malformed object (the mach header "<br>
+                         "extends past the end of the file)");<br>
+    return;<br>
+  }<br>
   if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))<br>
     Header = *HeaderOrErr;<br>
   else<br>
@@ -267,12 +272,22 @@ MachOObjectFile::MachOObjectFile(MemoryB<br>
       DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),<br>
       HasPageZeroSegment(false) {<br>
   ErrorAsOutParameter ErrAsOutParam(Err);<br>
-  if (is64Bit())<br>
+  uint64_t big_size;<br>
+  if (is64Bit()) {<br>
     parseHeader(this, Header64, Err);<br>
-  else<br>
+    big_size = sizeof(MachO::mach_header_64);<br>
+  } else {<br>
     parseHeader(this, Header, Err);<br>
+    big_size = sizeof(MachO::mach_header);<br>
+  }<br>
   if (Err)<br>
     return;<br>
+  big_size += getHeader().sizeofcmds;<br>
+  if (getData().data() + big_size > getData().end()) {<br>
+    Err = malformedError(getFileName(), "truncated or malformed object "<br>
+                         "(load commands extends past the end of the file)");<br></blockquote><div><br></div><div>Did you intend "load command extends" or "load commands extend"?</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    return;<br>
+  }<br>
<br>
   uint32_t LoadCommandCount = getHeader().ncmds;<br>
   if (LoadCommandCount == 0)<br>
<br>
Modified: llvm/trunk/test/Object/macho-invalid.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/macho-invalid.test?rev=266248&r1=266247&r2=266248&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/macho-invalid.test?rev=266248&r1=266247&r2=266248&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Object/macho-invalid.test (original)<br>
+++ llvm/trunk/test/Object/macho-invalid.test Wed Apr 13 16:17:58 2016<br>
@@ -9,11 +9,11 @@ RUN: not llvm-objdump -macho -private-he<br>
 RUN:      | FileCheck -check-prefix INCOMPLETE-LOADC %s<br>
 INCOMPLETE-LOADC: truncated or malformed object (load command 0 extends past the end all load commands in the file)<br>
<br>
-RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-too-small-load-command 2>&1 \<br>
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-too-small-load-command 2>&1 \<br>
 RUN:      | FileCheck -check-prefix SMALL-LOADC-SIZE %s<br>
-RUN: not llvm-objdump -private-headers %p/Inputs/macho64-invalid-too-small-load-command 2>&1 \<br>
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho64-invalid-too-small-load-command 2>&1 \<br>
 RUN:      | FileCheck -check-prefix SMALL-LOADC-SIZE %s<br>
-SMALL-LOADC-SIZE: Mach-O load command with size < 8 bytes<br>
+SMALL-LOADC-SIZE: truncated or malformed object (load commands extends past the end of the file)<br>
<br>
 RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-too-small-segment-load-command 2>&1 \<br>
 RUN:      | FileCheck -check-prefix SMALL-SEGLOADC-SIZE %s<br>
@@ -27,13 +27,12 @@ RUN: not llvm-objdump -private-headers %<br>
 RUN:      | FileCheck -check-prefix TOO-MANY-SECTS %s<br>
 TOO-MANY-SECTS: Mach-O segment load command contains too many sections<br>
<br>
-RUN: not llvm-objdump -t %p/Inputs/macho-invalid-bad-symbol-index 2>&1 \<br>
+RUN: not llvm-objdump -macho -t %p/Inputs/macho-invalid-bad-symbol-index 2>&1 \<br>
 RUN:      | FileCheck -check-prefix BAD-SYMBOL %s<br>
-BAD-SYMBOL: Invalid data was encountered while parsing the file.<br>
-RUN: llvm-objdump -t %p/Inputs/macho-valid-0-nsyms 2>&1 \<br>
+BAD-SYMBOL: truncated or malformed object (ilocalsym plus nlocalsym in LC_DYSYMTAB load command extends past the end of the symbol table)<br>
+RUN: llvm-objdump -macho -t %p/Inputs/macho-valid-0-nsyms 2>&1 \<br>
 RUN:      | FileCheck -check-prefix ZERO-NSYMS %s<br>
 ZERO-NSYMS: SYMBOL TABLE<br>
-ZERO-NSYMS-NOT: Requested symbol index is out of range<br>
<br>
 RUN: not llvm-objdump -t %p/Inputs/macho-invalid-symbol-name-past-eof 2>&1 \<br>
 RUN:      | FileCheck -check-prefix NAME-PAST-EOF %s<br>
@@ -58,9 +57,8 @@ RUN: not llvm-objdump -t %p/Inputs/macho<br>
 RUN:      | FileCheck -check-prefix INVALID-SECTION-IDX-SYMBOL-SEC-objdump %s<br>
 INVALID-SECTION-IDX-SYMBOL-SEC-objdump: Invalid data was encountered while parsing the file.<br>
<br>
-RUN: not llvm-objdump -private-headers %p/Inputs/macho-invalid-header 2>&1 | FileCheck -check-prefix INVALID-HEADER %s<br>
-INVALID-HEADER: The file was not recognized as a valid object file.<br>
-NOT-INVALID-HEADER: Invalid data was encountered while parsing the file.<br>
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-header 2>&1 | FileCheck -check-prefix INVALID-HEADER %s<br>
+INVALID-HEADER: The file was not recognized as a valid object file<br>
<br>
-RUN: not llvm-objdump -private-headers %p/Inputs/macho64-invalid-incomplete-segment-load-command 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC %s<br>
-INCOMPLETE-SEGMENT-LOADC: Invalid data was encountered while parsing the file<br>
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho64-invalid-incomplete-segment-load-command 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC %s<br>
+INCOMPLETE-SEGMENT-LOADC: truncated or malformed object (load commands extends past the end of the file)<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>