Allow DYLD Environment Variables Entitlement on OSX 10.13.6

I am trying to allow searching and loading libraries from non-standard locations using DYLD_LIBRARY_PATH. This is because of a mysql installation into /opt/mysql (and its libraries go to /opt/mysql/lib). I did not want to link all contents of /opt/mysql/lib into /usr/local/lib and so I tried to set the non-standard library location into DYLD_LIBRARY_PATH. But this fails to be passed on to applications which then fail to find the library, e.g. consider this example (from https://stackoverflow.com/questions/71947188/bash-variable-of-name-starting-with-dyld-is-not-loaded-into-environment-bug-o):

export DYLD_VARIABLE=Dd
export FYLD_VARIABLE=Ff
env | grep VARIABLE

(DYLD is not passed on whereas FYLD is)

So, I resorted changing the property for this behaviour with this from the Terminal:

defaults write com.apple.security.cs.allow-dyld-environment-variables true

but it says:

Rep argument is not a dictionary
Defaults have not been changed.

Also:

defaults find com.apple.security.cs

does not find said key.

But this page: https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-dyld-environment-variables

says that this property list key is there since 10.7+

As I said, I am on OSX 10.13.6.

My question is: how to allow DYLD_* env variables to be passed on?

You have misunderstood the advice from that Stack Overflow post you referenced. com.apple.security.cs.allow-dyld-environment-variables is not an preference but an entitlement that controls the behaviour of the hardened runtime.

Consider this tiny test program:

import Foundation

func main() {
    let s = ProcessInfo.processInfo.environment
        .filter { key, _ in
            key.starts(with: "DYLD_")
        }
        .map { key, value in
            "\(key)=\(value)"
        }
        .joined(separator: "\n")
    print(s)
}

main()

If I build it in the usual way it’s signed like this:

% codesign -d -vvv --entitlements - Test714782
…
CodeDirectory v=20500 size=726 flags=0x10000(runtime) …
…
[Dict]
    [Key] com.apple.security.get-task-allow
    [Value]
        [Bool] true

Note the presence of the runtime flag. This means that the hardened runtime is enabled. If I run it that way, it sees DYLD_ environment variables:

% DLYD_FOO=BAR ./Test714782

The com.apple.security.get-task-allow entitlement means “This is built for debugging.” and that prevents the hardened runtime from scrubbing DYLD_ environment variables.

You can disable that entitlement by setting the Code Signing Inject Base Entitlements (CODE_SIGN_INJECT_BASE_ENTITLEMENTS) build setting to false [1]. On doing that I see this for the tool’s signature:

% codesign -d -vvv --entitlements - Test714782
…
CodeDirectory v=20500 size=726 flags=0x10000(runtime) …
…
[Dict]

And now the hardened runtime scrubs DYLD_ environment variables:

% DYLD_FOO=BAR ./Test714782                   

To avoid this I set Allow DYLD Environment Variables in the Hardened Runtime section of Signing & Capabilities. The results in the tool being signed with the com.apple.security.cs.allow-dyld-environment-variables entitlement:

% codesign -d -vvv --entitlements - Test714782
…
CodeDirectory v=20500 size=726 flags=0x10000(runtime) …
…
[Dict]
    [Key] com.apple.security.cs.allow-dyld-environment-variables
    [Value]
        [Bool] true

And that disables the DYDLD_ scrubbing:

% DYLD_FOO=BAR ./Test714782                   
DYLD_FOO=BAR

I tested this on macOS 12.5.1 with Xcode 14.0 but AFAIK this behaviour is the same all the way back to the introduction of the hardened runtime.

Share and Enjoy

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

[1] Xcode also disables it when you export a release-signed version from the organiser, but in this case I want to disable it for the development-signed version built using Product > Build.

I sure did misunderstand the Hardened Runtime. THANK you for your informative reply.

I don't need this for an application of my own. I want all applications I am running through my bash shell to be able to see DYLD_* variables from the environment. (currently make gives me this problem).

I believe make was installed by homebrew. And I guess other applications, like cmake may also behave similarly. But I guess it is too much of a hassle for me to codesign each and every executable that may need to read DYLD_* variables. The hassle being that on each upgrade of make I need to do the codesigns again for each executable. Unless I do : find /usr/local/bin -type f -exec codesign -d -vvv --entitlements - \{\} \; which is like the nuclear option really.

I guess I need to disable globally this Hardened Runtime by disabling SIP (which I have refrained from doing over the last 7 years).

Any other options? (Do I need to make a new post?) THANK YOU

Do I need to make a new post?

I’m happy to continue discussing things here.

I guess I need to disable globally this Hardened Runtime by disabling SIP

That’s certainly an option, but it’s not something I’d do on a machine that I care about.

Like many things this is a trade-off. Do you want to disable SIP? Or do you want to put the libraries, or symlinks to the libraries, in the usr/local/lib? I know which one I’d prefer.

Share and Enjoy

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

Allow DYLD Environment Variables Entitlement on OSX 10.13.6
 
 
Q