Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dylib Library not loaded due to restricted binary after apple code signing

I put a executable binary XXX in my app works on MacOS ,and code sign it. My app will use this service through port.

Executable binary XXX will register a service through plist file after install my app , plist file contains DYLD_LIBRARY_PATH which tells executable binary where to find the dylib to use.

launchctl load -wF "$HOME/Library/LaunchAgents/local.plist"

launchctl start local

Here is the problem:

it worked fine after i build a app.

but when i signed it all and notarized, then open my app to use ,it would get errors as follow:

dyld: Library not loaded: @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib
Referenced from: /Users/buffer/Library/Application Support/XXX
Reason: unsafe use of relative rpath @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib in /Users/buffer/Library/Application Support/XXX with restricted binary

It will use default dylib path(@@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib) that comes from executable binary XXX, not my custom DYLD_LIBRARY_PATH. Apple has restricted binary use such unsafe relative rpath.

Updated:

My app will start a shell script to install executable binary XXX and dylib , Executable binary XXX will register as a service to start and stop through plist as below

launchctl load -wF "$HOME/Library/LaunchAgents/local.plist"

launchctl start local

My executable binary XXX path and DYLD_LIBRARY_PATH both located at /Users/buffer/Library/Application Support/myApp/*** , it start separately as a service for my app to use.

I have found some situations below:

1.I have a same executable binary XXX signed at 2018-09-25 , it works fine.

2.And executable binary XXX that have not been signed worked fine too.

3.But when i have signed executable binary XXX now and use it with dylib , it will get errors above.

So ,whether apple sign algorithm has changed and make this error occurs ? here is my code sign command for now as below:

codesign --force --options runtime --sign "Developer ID Application: ****" XXX

Finally:

I have found problem, Apple require developer enable Hardened runtime for every app to notrize now. if you enable Hardened runtime but not specify entitlements , then some permissions will be disabled as default .

My permission for use DYLD Environment Variables has been disabled as default

you can check this document below

Hardened Runtime Entitlements

If you customize code sign workflow like me , you can specify entitlements when you codesign as below,entitlements.plist contains permissions you want enable

codesign --force --options runtime --entitlements /Users/buffer/Desktop/entitlements.plist  --sign "Developer ID Application: ****" XXX
like image 355
Buffer Avatar asked Aug 27 '19 03:08

Buffer


2 Answers

As of macOS 10.10.4, for security reasons, you are not allowed to use a dylib outside the directories that Apple deems as secure as, for example:

/System/
/usr/bin/
/Library/Frameworks/

The code signing documentation entitled "Checking Gatekeeper Conformance" expressly states that:

Beginning with macOS 10.10.4, Gatekeeper verifies that no libraries are loaded from outside an app bundle. If an app uses @rpath or an absolute path to link to a dynamic library outside of the app, Gatekeeper rejects the app. This restriction applies to the app’s main executable and any other executable in the bundle, including libraries. This restriction applies even if the path does not exist (which normally causes the dynamic linker to fall back to a library inside the bundle). The error will appear in the system log, with a message like the following for an app MyApp.app trying to link against the library libLibrary.dylib in the nonstandard location /foo

Thus, you should embed your dylib inside your application.

Apparently, another possible solution is to use a signed installer to install a common framework at /Library/Frameworks/, but this solution was offered by DTS, and is apparently not part of the official documentation.

like image 120
jvarela Avatar answered Nov 10 '22 07:11

jvarela


I learned from Apple DTS that there is a known bug in macOS Catalina 10.15.3 and earlier (already fixed in 10.15.4 beta) wherein a notarized command line app that links against a .dylib outside of its bundle (and command line apps are typically not in a bundle) will still fail Gatekeeper checks that trigger when the quarantine flag is set on the command line executable.

To workaround the problem, Apple DTS recommends:

The easiest workaround is to sign your tool with both the hardened runtime and library validation flags.

That is, change your invocation of codesign from this:

% codesign -s …stuff… -o runtime …stuff… helloworld

to this:

% codesign -s …stuff… -o runtime,library …stuff… helloworld

Explicitly setting the library flag disables this Gatekeeper check and allows your tool to run on macOS 10.15.{0,1,2,3}. Please make a note to remove this flag once 10.15.4 is released and widely adopted.

like image 28
Bill Feth Avatar answered Nov 10 '22 06:11

Bill Feth