Executable won't execute despite signed/notarized

When trying to execute an executable (on 10.14.7), I get a dialog box saying:


“Main” cannot be opened because the developer cannot be verified.

macOS cannot verify this app is free from malware.

This executable cames from a .dmg which is signed, notarized and stapled successfully.

Code Block
stapler validate /Users/jtripoz/Downloads/XXX.dmg 
Processing: /Users/jtripoz/Downloads/XXX.dmg
The validate action worked!


Code Block
codesign -dvvv /Users/jtripoz/Downloads/XXX.dmg 
Executable=/Users/jtripoz/Downloads/XXX.dmg
Identifier=com.xxx.xxx
Format=disk image
CodeDirectory v=20200 size=309 flags=0x0(none) hashes=1+6 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=xxx
CandidateCDHashFull sha256=xxx
Hash choices=sha256
CMSDigest=xxx
CMSDigestType=2
CDHash=xxx
Signature size=8959
Authority=Developer ID Application: XXX (xxxxxxxxx)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=4 Mar 2021 at 15:35:28
Info.plist=not bound
TeamIdentifier=XXX
Sealed Resources=none
Internal requirements count=1 size=184

and the executable is signed/hardened:

Code Block
codesign -dvvv ./Main
Executable=xxx/Main
Identifier=Main
Format=Mach-O thin (x86_64)
CodeDirectory v=20500 size=13680 flags=0x10000(runtime) hashes=419+5 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha256=xxx
CandidateCDHashFull sha256=xxx
Hash choices=sha256
CMSDigest=xxx
CMSDigestType=2
CDHash=xxx
Signature size=8960
Authority=Developer ID Application: XXX (XXXXXXX)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=4 Mar 2021 at 15:33:59
Info.plist=not bound
TeamIdentifier=XXXXX
Runtime Version=10.15.0
Sealed Resources=none
Internal requirements count=1 size=164

And has 2 entitlements:

codesign -d --entitlements :- Main
Code Block
Executable=xxx/Main
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>

I'm running on 10.15.7, and assessments are enabled.

Code Block
spctl --status
assessments enabled


What did I missed ?

TIA,

J.


Why are you disabling library validation? This actually makes it harder to pass Gatekeeper, so you should only do it if you absolutely must (for example, if your code loads third-party plug-ins).

Share and Enjoy

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

Yes, I use a lot of libraries - eg. Boost, ImageMagick, Xerces, XQilla, ... - that I build from sources.

Plus another one 'dpmac64.dylib' which is used for protection.

Nevertheless, I've made a attempt without the com.apple.security.cs.disable-library-validation entitelment and when I run the command:

Code Block
DYLD_LIBRARY_PATH=./lib ./Main


I get this issue:


dyld: Library not loaded: dpmac64.dylib
 Referenced from: ...../Main
 Reason: no suitable image found. Did find:
./lib/dpmac64.dylib: code signing blocked mmap() of './lib/dpmac64.dylib'
./lib/dpmac64.dylib: stat() failed with errno=1

dpmac64.dylib resides in the lib folder (set by the DYLD_LIBRARY_PATH)

Main requires it:

Code Block
otool -L Main
Main:
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 162.0.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 52.0.0)
dpmac64.dylib (compatibility version 0.0.0, current version 0.0.0)
....

It is signed:

Code Block
codesign -dvvv lib/dpmac64.dylib
Executable=....../lib/dpmac64.dylib
Identifier=dpmac64
Format=Mach-O thin (x86_64)
CodeDirectory v=20200 size=1543 flags=0x0(none) hashes=44+2 location=embedded
Hash type=sha256 size=32
CandidateCDHash sha1=xxxx
CandidateCDHashFull sha1=xxxx
CandidateCDHash sha256=xxxx
CandidateCDHashFull sha256=xxxx
Hash choices=sha1,sha256
CMSDigest=xxxx
CMSDigestType=2
CDHash=xxx
Signature size=9040
Authority=Developer ID Application: XXXX (xxx)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=15 Feb 2021 at 16:57:43
Info.plist=not bound
TeamIdentifier=XXXX
Sealed Resources=none
Internal requirements count=1 size=168

and it uses quite regular libs:

Code Block
otool -L lib/dpmac64.dylib
lib/dpmac64.dylib:
dpmac64.dylib (compatibility version 0.0.0, current version 0.0.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.19.0)
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 32.0.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 830.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)


When doing previous tests, signing Main with the 2 entitelments (allow-dyld-environment-variables + disable-library-validation) fixed the problem. But the main difference is that I made it locally for tests (directly on the Main file) - here, I have downloaded the notarized DMG containing the files.

If I re-sign Main with the entitlements and run

Code Block
DYLD_LIBRARY_PATH=./lib ./Main

I get the same dialog box saying "“Main” cannot be opened because the developer cannot be verified. macOS cannot verify that this app is free from malware. Chrome downloaded it ..."

If I remove the quarantine attribute, using

Code Block
xattr -remove com.apple.quarantine Main


then rerun

Code Block
DYLD_LIBRARY_PATH=./lib ./Main


everything seems OK.

So... what's wrong ?

TIA,

J.



Yes, I use a lot of libraries … that I build from sources.

Plus another one dpmac64.dylib which is used for protection.

Presumably you distribute all of this as part of your product. If so, you should sign it as your code and then ship with library validation enabled.

set by the DYLD_LIBRARY_PATH

In most cases you should avoid using DYLD_LIBRARY_PATH in production code. That environment variable is best used for debugging and quick hacks (-:

The recommended alternative is to lean into the rpath mechanism. See the dyld man page for details.

I get the same dialog box saying “Main” cannot be opened because the developer cannot be verified. macOS cannot verify that this app is free from malware …

Right. This is a Gatekeeper alert.

If I remove the quarantine attribute

Gatekeeper only kicks in for quarantined code [1], which explain why this avoids the problem.



Earlier on you mentioned 10.14.7…

When trying to execute an executable (on 10.14.7)

but you also mentioned 10.15.7…

I'm running on 10.15.7, and assessments are enabled.

Is the first one a typo?

This matters because Gatekeeper changed quite a bit during the late 10.14 and earlier 10.15 time period, and that affects what you can ‘get away with’ here (-:

Share and Enjoy

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

[1] This isn’t quite true. Gatekeeper checks certain types of code even if it’s not quarantined, but that doesn’t apply for a command line tool.
Hi Quinn.

I'm running on Catalina, 10.15.7. It was a typo.

The main thing I don't understand, is this:

Code Block
dyld: Library not loaded: dpmac64.dylib Referenced from: ...../Main Reason: no suitable image found. Did find: ./lib/dpmac64.dylib: code signing blocked mmap() of './lib/dpmac64.dylib' ./lib/dpmac64.dylib: stat() failed with errno=1

It means that the library was found - right, it is in lib, and lib has been added to library search path (OK, I know this is not the most secure, I'll have a look to @rpath stuff as well) but why is it blocked ?

What means this:
Code Block
code signing blocked mmap() of './lib/dpmac64.dylib'


And, how could I fix it ?

TIA,

J.

What means this:

There’s a variety of potential reasons for this, including:
  • The library isn’t signed.

  • The library is signed with restricted entitlements — Signing a library with entitlements never makes any sense because entitlements are only effective on a main executable.

  • The library is signed but the kernel rejected its code signature because of a deployment target issue — See Notarisation and the macOS 10.9 SDK for more info on this.

Share and Enjoy

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

Looks like it is the 3rd case: The library is signed but the kernel rejected its code signature because of a deployment target issue

In fact, this library seemed to have NO LC_VERSION_MIN_MACOSX set....

What is strange is that the notarization did not moan - I remember an error when a dylib had a LC_VERSION_MIN_MACOSX < 10.9

Once added with vtool is seems OK - at least for this problem.

I've managed to use @rpath and thus no entitlements, but still some issues, I'll open a new case if necessary.

Thanks for your help,

J.
Executable won't execute despite signed/notarized
 
 
Q