Making a signed and notarised 'Unix' app

Hi forum,

First be aware that I'm quite a newby re MacOS development so my questions may sound simple / stupid 😊
 
I’m faced to a problem similar to:

https://developer.apple.com/forums/thread/122592

I’ve understood that for notarization:
  • The exececutable (diagnose) must be signed with hardening option

  • This hardening prevents using dylibs which are not in ‘secure’ system location, OR in the ‘bundle’

 
I’ve seen Quinn's answer in the same post, 



The most likely problem here is the connection between your main executable and your libraries. Gatekeeper supports two standard models for this:
·         The main executable is in a bundle, and the libraries are nested within that bundle in 
Contents/Frameworks/
. This is the approach used by apps and other bundled code.
·         The main executable links to the libraries in a fixed location, typically 
/Library/Frameworks/
 

 
Would it be possible to get a how-to or a short example (XCode project) with 1 executable and 2 dylibs arranged this way ?
 
I’ve also read that it’s possible to allow some extra places for libraries – using entitlements, using a .plist file. Would it be possible to have an example as well ?
 
TIA,

J.

Would it be possible to get a how-to or a short example (Xcode
project) with 1 executable and 2 dylibs arranged this way?

Are you building these shared libraries from source? Or using someone’s pre-built libraries?

Share and Enjoy

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


In the meantime, I've found a suitable workaround (I've not done the entire process with notarisation, but according to documentation it should work...)

With a Main (executable) using myLib.dylib:
  • use install_name_tool to tell Main to use myLib.dylib (without any path)

  • use install_name_tool to set myLib.dylib installname to myLib.dylib (without any path)

  • place myLib.dylib in a subfolder libs

  • codesign myLib.dylib with usual settings

  • codesign Main with hardening and the entitlement com.apple.security.cs.allow-dyld-environment-variables

Code Block language XML
<?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/>
</dict>
</plist>
  • run Main with DYLD_LIBRARY_PATH=./libs ./Main


Should work for https://developer.apple.com/forums/thread/122592 as well - just providing the right DYLD_LIBRARY_PATH.


J.

First up, try to statically link as much as you can. Remember that shared libraries are only a win if they’re actually shared, which is quite rare on modern systems. An un-shared shared library complicates your build process and slows down your launch time.

Second, dyld environment variables are rarely the right answer to distribution problems. They have their place — for example, Xcode uses them to ensure that your tool links to the most up-to-date library when you run it in the debugger — but that’s almost exclusively in the preserve of tools and hacks. You shouldn’t rely on them for distribution.

Finally, you shouldn’t need to resort to such shenanigans. On modern systems Gatekeeper will only complain about references outside of your bundle (which is obviously an issue for you because you don’t have a bundle) if you have library validation disabled. Library validation is enabled by the hardened runtime, so as long as you don’t explicitly disable it (using com.apple.security.cs.disable-library-validation) then such references work just fine.

Consider this:

Code Block
% # Testing on 11.1 (I really need to update to 11.2!).
%
% sw_vers
ProductName: macOS
ProductVersion: 11.1
BuildVersion: 20C69
%
% # I have a `Test673862.dmg` disk image.
%
% ls -lh Test673862.dmg
-rw-r--r--@ 1 quinn staff 45K 16 Feb 11:26 Test673862.dmg
%
% # Which is mounted as quarantined.
%
% mount
/dev/disk3s1 on /Volumes/Test673862Root (…, quarantine, …)
%
% # I can run my tool off it just fine.
%
% /Volumes/Test673862Root/Test673862
42
%
% # The tool consists of a tool and a shared library.
%
% ls -lh /Volumes/Test673862Root
total 528
-rwxr-xr-x 1 quinn staff 163K 16 Feb 11:22 Test673862
-rwxr-xr-x 1 quinn staff 99K 16 Feb 11:22 libTest673862.dylib
%
% # The tool references the library via `@rpath`.
%
% otool -L /Volumes/Test673862Root/Test673862
/Volumes/Test673862Root/Test673862:
@rpath/libTest673862.dylib …
%
% # Which is resolved via `@executable_path`.
%
% otool -l /Volumes/Test673862Root/Test673862 | grep -B 1 -A 2 RPATH
Load command 17
cmd LC_RPATH
cmdsize 32
path @executable_path (offset 12)
%
% # And the hardened runtime is enabled with no
% # `com.apple.security.cs.disable-library-validation` entitlement
% # to disable library validation.
%
% codesign -d --entitlements :- -vvv /Volumes/Test673862Root/Test673862
CodeDirectory v=20500 size=598 flags=0x10000(runtime) …
%


Share and Enjoy

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

I'll try to reproduce you sample.

Cheers ,

J.
Making a signed and notarised 'Unix' app
 
 
Q