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

2024-04-29

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

如果我在 shell 中设置这些环境变量:

export PYTHONHOME=${HOME}/anaconda
export DYLD_INSERT_LIBRARIES=${HOME}/anaconda/lib/libpython2.7.dylib:${HOME}/anaconda/lib/libmkl_rt.dylib

如果我直接启动我的应用程序,它可以正常工作。但是,如果我通过我编写的 bash 脚本调用它,DYLD_INSERT_LIBRARIES被忽略。

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

看起来像DYLD_INSERT_LIBRARIES正如此测试脚本所证明的那样,当调用 bash 脚本时,该值被取消设置。

#!/bin/bash
set -e
echo ${DYLD_INSERT_LIBRARIES}

有没有办法让bash脚本继承并传承下来DYLD_INSERT_LIBRARIES?


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

系统bash可执行文件已被标记为“受限”,禁用 DYLD_* 功能。要解决此问题,您可以复制bash并用它来代替。

通过在实现中查找以下细节dyld,我看到这个限制至少可以追溯到 10.6。

在 macOS 10.13 中dyld 执行 https://opensource.apple.com/source/dyld/dyld-519.2.1/src/dyld.cpp.auto.html这个逻辑在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.

然而,设置限制的实际逻辑是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;
...

正如你所看到的,这取决于,issetugid, hasRestrictedSegment,以及CS_RESTRICT/SIP 权利。您也许可以直接测试受限状态,或者您可以构建一个函数来根据此信息自行测试这些条件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 bash 调用应用程序时忽略 dyld_insert_libraries 的相关文章

随机推荐