summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2016-10-11 21:04:39 +0000
committerKevin Enderby <enderby@apple.com>2016-10-11 21:04:39 +0000
commit68fffa8a62f1d0262302f3a19c92f4c5cdc314ea (patch)
tree5166ed2acbac812fd49c014b0d67ebc7aef5c4fc
parentf4876beb2b700a1672b6e61f093c043e57953b3c (diff)
downloadbcm5719-llvm-68fffa8a62f1d0262302f3a19c92f4c5cdc314ea.tar.gz
bcm5719-llvm-68fffa8a62f1d0262302f3a19c92f4c5cdc314ea.zip
Next set of additional error checks for invalid Mach-O files for the
load commands that uses the MachO::linker_option_command type but not used in llvm libObject code but used in llvm tool code. This includes just LC_LINKER_OPTION load command. llvm-svn: 283939
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp36
-rw-r--r--llvm/test/Object/Inputs/macho-invalid-linkopt-bad-countbin0 -> 48 bytes
-rw-r--r--llvm/test/Object/Inputs/macho-invalid-linkopt-bad-sizebin0 -> 44 bytes
-rw-r--r--llvm/test/Object/macho-invalid.test6
4 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index b5d1f934b63..2c93ecbf2b9 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -722,6 +722,39 @@ static Error checkEncryptCommand(const MachOObjectFile *Obj,
return Error::success();
}
+static Error checkLinkerOptCommand(const MachOObjectFile *Obj,
+ const MachOObjectFile::LoadCommandInfo &Load,
+ uint32_t LoadCommandIndex) {
+ if (Load.C.cmdsize < sizeof(MachO::linker_option_command))
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " LC_LINKER_OPTION cmdsize too small");
+ MachO::linker_option_command L =
+ getStruct<MachO::linker_option_command>(Obj, Load.Ptr);
+ // Make sure the count of strings is correct.
+ const char *string = (const char *)Load.Ptr +
+ sizeof(struct MachO::linker_option_command);
+ uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command);
+ uint32_t i = 0;
+ while (left > 0) {
+ while (*string == '\0' && left > 0) {
+ string++;
+ left--;
+ }
+ if (left > 0) {
+ i++;
+ uint32_t NullPos = StringRef(string, left).find('\0');
+ uint32_t len = std::min(NullPos, left) + 1;
+ string += len;
+ left -= len;
+ }
+ }
+ if (L.count != i)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " LC_LINKER_OPTION string count " + Twine(L.count) +
+ " does not match number of strings");
+ return Error::success();
+}
+
Expected<std::unique_ptr<MachOObjectFile>>
MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
bool Is64Bits) {
@@ -950,6 +983,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
if ((Err = checkEncryptCommand(this, Load, I, E.cryptoff, E.cryptsize,
&EncryptLoadCmd, "LC_ENCRYPTION_INFO_64")))
return;
+ } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) {
+ if ((Err = checkLinkerOptCommand(this, Load, I)))
+ return;
}
if (I < LoadCommandCount - 1) {
if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
diff --git a/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-count b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-count
new file mode 100644
index 00000000000..85f35790b46
--- /dev/null
+++ b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-count
Binary files differ
diff --git a/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size
new file mode 100644
index 00000000000..a7b521fc411
--- /dev/null
+++ b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size
Binary files differ
diff --git a/llvm/test/Object/macho-invalid.test b/llvm/test/Object/macho-invalid.test
index cf85dac689d..31948d8505e 100644
--- a/llvm/test/Object/macho-invalid.test
+++ b/llvm/test/Object/macho-invalid.test
@@ -349,3 +349,9 @@ INVALID-ENCRYPT-CRYPTOFF: macho-invalid-encrypt-cryptoff': truncated or malforme
RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-encrypt64-cryptoff-cryptsize 2>&1 | FileCheck -check-prefix INVALID-ENCRYPT-CRYPTOFF-CRYPTSIZE %s
INVALID-ENCRYPT-CRYPTOFF-CRYPTSIZE: macho-invalid-encrypt64-cryptoff-cryptsize': truncated or malformed object (cryptoff field plus cryptsize field of LC_ENCRYPTION_INFO_64 command 0 extends past the end of the file)
+
+RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-invalid-linkopt-bad-size 2>&1 | FileCheck -check-prefix INVALID-LINKOPT-BAD-SIZE %s
+INVALID-LINKOPT-BAD-SIZE: macho-invalid-linkopt-bad-size': truncated or malformed object (load command 0 LC_LINKER_OPTION cmdsize too small)
+
+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)
OpenPOWER on IntegriCloud