Skip to content

Commit

Permalink
Next set of additional error checks for invalid Mach-O files for the
Browse files Browse the repository at this point in the history
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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283939 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
enderby committed Oct 11, 2016
1 parent 63d2a1d commit 9a96669
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 deletions.
36 changes: 36 additions & 0 deletions lib/Object/MachOObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down
Binary file added test/Object/Inputs/macho-invalid-linkopt-bad-count
Binary file not shown.
Binary file added test/Object/Inputs/macho-invalid-linkopt-bad-size
Binary file not shown.
6 changes: 6 additions & 0 deletions test/Object/macho-invalid.test
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 9a96669

Please sign in to comment.