Codesign and AppStore verification failure after manually lipo'ing two dylibs

We are creating a universal build of our application for the Mac App Store by merging separate x86_64 and arm64 bundles using a script.

Codesign verification fails for some dylibs if they are signed after merging:

% lipo -create x86_64/test.dylib arm64/test.dylib -o universal/test.dylib
% codesign -s *** -f --timestamp universal/test.dylib
% codesign --verify --verbose=2 universal/test.dylib
test.dylib: invalid Info.plist (plist or signature have been modified)

It seems verification fails for only those dylibs that have an Info.plist embedded in them.

We were able to work around this issue by signing the individual dylibs before merging, but now AppStore verification is failing with the following error:

ITMS-90336: Mismatched Embedded Info.plist: The executable 'test.dylib' has mismatched embedded Info.plists. This could be due to the use of 3rd party build tools.

Does this mean that the __info_plist section in all the slices in the universal binary should be exactly the same (bitwise)? Some of these are third-party binaries and we don't know whether they were created using third-party build tools.

Accepted Reply

This issue rarely crops up in practice because:

  • Apple-oriented developers tend to create a framework, and that has a single Info.plist file for all architectures.

  • Other developers, the ones most likely to use a standalone dynamic library, don’t rely on the Info.plist.

In theory the code signatures of each Mach-O architecture should be completely independent but it’s not something I’d want to rely on (the last time I looked at code signature structures in depth I vaguely recall seeing a technical reason for this sort of coupling but I don’t remember the details).

Does this mean that the __info_plist section in all the slices in the universal binary should be exactly the same (bitwise)?

That would have been my recommendation if you’d asked me this question in a vacuum. And it seems that opinion is born out by the App Store check you’re hitting.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Replies

This issue rarely crops up in practice because:

  • Apple-oriented developers tend to create a framework, and that has a single Info.plist file for all architectures.

  • Other developers, the ones most likely to use a standalone dynamic library, don’t rely on the Info.plist.

In theory the code signatures of each Mach-O architecture should be completely independent but it’s not something I’d want to rely on (the last time I looked at code signature structures in depth I vaguely recall seeing a technical reason for this sort of coupling but I don’t remember the details).

Does this mean that the __info_plist section in all the slices in the universal binary should be exactly the same (bitwise)?

That would have been my recommendation if you’d asked me this question in a vacuum. And it seems that opinion is born out by the App Store check you’re hitting.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Apple-oriented developers tend to create a framework, and that has a single Info.plist file for all architectures.

This issue can happen even if the user has a single Info.plist file for all architectures. In our case, a helper tool has a single Info.plist for both architectures with exactly the same keys and values but Xcode inserts a different value for the key BuildMachineOSBuild if the x86_64 and arm64 binaries are compiled on machines with different OS Build versions, resulting in verification failure.

This issue can happen even if the user has a single Info.plist file for all architectures.

Right. But I was specifically talking about frameworks. In a framework the Info.plist file is on disk, not embedded in the Mach-O, and thus there can only be one of them. So, if you merge two frameworks together, any Info.plist conflicts becomes a file merge issue, which is different from this issue.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"