通过bash调用应用程序时dyld_insert_libraries被忽略

Jua*_*uan 3 macos bash shared-libraries

对于我的应用程序,我正在使用DYLD_INSERT_LIBRARIES来切换库。我正在运行Mac OS X,El Capitan。

如果在外壳程序中设置以下环境变量:

export PYTHONHOME=${HOME}/anaconda
export DYLD_INSERT_LIBRARIES=${HOME}/anaconda/lib/libpython2.7.dylib:${HOME}/anaconda/lib/libmkl_rt.dylib
Run Code Online (Sandbox Code Playgroud)

如果我直接启动我的应用程序,它将正常运行。但是,如果我通过编写的bash脚本调用它,则将DYLD_INSERT_LIBRARIES被忽略。

如果将相同的两行添加到bash脚本中,则我的应用程序将再次运行。

DYLD_INSERT_LIBRARIES测试脚本所示,调用bash脚本时似乎未设置。

#!/bin/bash
set -e
echo ${DYLD_INSERT_LIBRARIES}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以让bash脚本继承并传递DYLD_INSERT_LIBRARIES

gwk*_*gwk 6

这是最新的macOS版本的安全功能。

系统bash可执行文件已被标记为“受限”,从而禁用了DYLD_ *功能。要变通解决此问题,您可以复制该副本bash并使用它。

通过在的实现中查找以下详细信息dyld,我看到此限制至少可以追溯到10.6。

在macOS 10.13 dyld 实现中,此逻辑在中pruneEnvironmentVariables,带有注释:

// For security, setuid programs ignore DYLD_* environment variables.
// Additionally, the DYLD_* enviroment variables are removed
// from the environment, so that any child processes don't see them.
Run Code Online (Sandbox Code Playgroud)

但是,设置限制的实际逻辑是configureProcessRestrictions

// any processes with setuid or setgid bit set or with __RESTRICT segment is restricted
if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) {
    gLinkContext.processIsRestricted = true;
}
...
if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) {
    // On OS X CS_RESTRICT means the program was signed with entitlements
    if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP ) {
        gLinkContext.processIsRestricted = true;
    }
    // Library Validation loosens searching but requires everything to be code signed
    if ( flags & CS_REQUIRE_LV ) {
        gLinkContext.processIsRestricted = false;
...
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这取决于,issetugidhasRestrictedSegment,和CS_RESTRICT/ SIP权利。您可能可以直接测试受限状态,也可以根据此信息自己构造一个功能来测试这些条件。