Authorization Plug-ins in /Library/Security/SecurityAgentPlugins unable to load @rpath dylibs

Originator:frogor.fb.openradar
Number:rdar://42528101 Date Originated:23-Jul-2018 09:25 PM
Status:Open Resolved:
Product:macOS + SDK Product Version:10.14 beta 4 (18A336e)
Classification:Serious Bug Reproducible:Always
 
Summary:
Swift-based authorization plug-ins fail to load in 10.14 beta 4 (18A336e) at the loginwindow (and possibly elsewhere).

This bug was also present in macOS 10.14 developer beta 2 (18A314h).

This bug was not present in macOS 10.14 developer beta 3 (18A326g).

This is a serious bug regression in beta 4.

Potential number of affected devices: In excess of 40,000. Uncorrected, this will be a blocker for 10.14 adoption.

Steps to Reproduce:
1. Write any Authorization Plug-in in Swift meant for the loginwindow.
2. Install it (by placing it at /Library/Security/SecurityAgentPlugins, owned by root:wheel, and configuring the authorizationdb mechanisms for system.login.console to load it)
3. Attempt to use it by logging in at the loginwindow.

If you don't have on available, you can use this open source one: https://github.com/grahamgilbert/crypt/releases

The pkg provided also includes a postinstall script that configures the authorization database to load the plug-in at the loginwindow.

Expected Results:
The plug-in loads and executes and login completes.

Actual Results:
dlopen throws an error with the inability to load any of the embedded Swift dynamic libraries (as placed there by Xcode during compile), visible by running this command as root via ssh: sudo log stream --info --debug --style=json

Messages similar to this (depending on your plug-in) will appear:

"eventMessage" : "Error loading \/Library\/Security\/SecurityAgentPlugins\/Crypt.bundle\/Contents\/MacOS\/Crypt:  dlopen(\/Library\/Security\/SecurityAgentPlugins\/Crypt.bundle\/Contents\/MacOS\/Crypt, 0x0106): dependent dylib '@rpath\/libswiftAppKit.dylib' not found for '\/Library\/Security\/SecurityAgentPlugins\/Crypt.bundle\/Contents\/MacOS\/Crypt'"

It does not matter what plug-in you attempt this with - it doesn't even need to be Swift-based. It just needs to attempt to load a dynamic library from an rpath.

Version:
10.14 beta 4 (18A336e)

Notes:
The bug appears to be that either LD_RPATH commands are ignored in the mach-o binary of the plug-in (or that dlopen path resolving is not properly taking them into account).

As a workaround, I used install_name_tool to rewrite all relative path dynamic libraries (like "@rpath/libswiftAppKit.dylib") to fully qualified paths referencing the installation path of the plug-in ("/Library/Security/SecurityAgentPlugins/Crypt.bundle/Contents/Frameworks/libswiftAppKit.dylib")

After doing this, the plug-in loaded with no problems and ran as expected - with absolutely no changes to the code of the plug-in itself. This also corrected the issue for Objective-C based plug-ins that included internal Framework resources.

Comments

Just an update this is still broken as of 10.14 beta5


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!