-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Description
Symptom
Artificial MachO binary processed by llvm-objcopy/strip is not accepted by codesign.
codesign fails with error:
main executable failed strict validation
Investigation
According to Darling/libsecurity_utilities/lib/macho++.cpp
libsecurity_utilities/lib/macho++.cpp|238 col 3| mSuspicious = true;
libsecurity_utilities/lib/macho++.cpp|617 col 7| mSuspicious = true;
libsecurity_utilities/lib/macho++.cpp|629 col 7| mSuspicious = true;
libsecurity_utilities/lib/macho++.cpp|635 col 8| mSuspicious = true;
libsecurity_utilities/lib/macho++.cpp|643 col 6| mSuspicious = true;
libsecurity_utilities/lib/macho++.cpp|654 col 5| mSuspicious = true;
According to MachO::validateStructure
- The sum of the last
LoadCommand
and its size must equal to the total size of "fat" component,
which sometimes corresponds to the end of file.
According to Universal::Universal
- Alignment of "fat" components must be less than 2^30, and
- The gap size between "fat" components must be less than its alignment.
- The gap must be filled with zero bytes.
- No junk shall be past end of file or "fat" component.
Relevant requirement
From the above there should be no data in MachO past contents of a load command with the largest offset+size
.
Problem description
llvm-objcopy
does not update indirectsymoff
field if the resulting IndirectSymTable
(after stripping) is empty [1]. As a result indirectsymoff
keeps old value, which is garbage, and can point past offset+size
of the last load command. As a result totalSize()
returns size that is larger than the actual stripped MachO [2].
This clearly violates one of the checks mentioned above (there are zero-bytes filled past offset+size
of the last load command.
- [1]
llvm-project/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
Lines 364 to 368 in ec41462
if (!O.IndirectSymTable.Symbols.empty()) { MLC.dysymtab_command_data.indirectsymoff = StartOfIndirectSymbols; MLC.dysymtab_command_data.nindirectsyms = O.IndirectSymTable.Symbols.size(); } - [2]
llvm-project/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
Lines 92 to 94 in ec41462
if (DySymTabCommand.indirectsymoff) Ends.push_back(DySymTabCommand.indirectsymoff + sizeof(uint32_t) * O.IndirectSymTable.Symbols.size());