diff options
author | Kevin Enderby <enderby@apple.com> | 2016-10-11 21:04:39 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2016-10-11 21:04:39 +0000 |
commit | 68fffa8a62f1d0262302f3a19c92f4c5cdc314ea (patch) | |
tree | 5166ed2acbac812fd49c014b0d67ebc7aef5c4fc | |
parent | f4876beb2b700a1672b6e61f093c043e57953b3c (diff) | |
download | bcm5719-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.cpp | 36 | ||||
-rw-r--r-- | llvm/test/Object/Inputs/macho-invalid-linkopt-bad-count | bin | 0 -> 48 bytes | |||
-rw-r--r-- | llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size | bin | 0 -> 44 bytes | |||
-rw-r--r-- | llvm/test/Object/macho-invalid.test | 6 |
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 Binary files differnew file mode 100644 index 00000000000..85f35790b46 --- /dev/null +++ b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-count diff --git a/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size Binary files differnew file mode 100644 index 00000000000..a7b521fc411 --- /dev/null +++ b/llvm/test/Object/Inputs/macho-invalid-linkopt-bad-size 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) |