本文介绍了通过bash调用应用程序时dyld_insert_libraries被忽略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For my application, I am using DYLD_INSERT_LIBRARIES to switch libraries. I am running Mac OS X, El Capitan.

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

If I set these environment variables in my 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 .

If I launch my application directly, it works properly. However, if I call it through a bash script I have written, the DYLD_INSERT_LIBRARIES is ignored.

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

If I add the same 2 lines to my bash script, my application works again.

调用此bash脚本时,好像未设置 DYLD_INSERT_LIBRARIES

It looks like DYLD_INSERT_LIBRARIES is being unset when the bash script is called, as proven by this test script.

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

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

Is there any way to let the bash script inherit and pass down DYLD_INSERT_LIBRARIES?

推荐答案

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

This is a security feature of recent macOS versions.

系统 bash 可执行文件已被标记为受限制",从而禁用了DYLD_ *功能.要解决此问题,您可以复制 bash 并将其替换.

The system bash executable has been marked as "restricted", disabling the DYLD_* features. To work around this, you can make a copy of bash and use that instead.

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

By looking for the following details in the implementations of dyld, I see that this restriction goes back at least to 10.6.

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

In the macOS 10.13 dyld implementation this logic is in pruneEnvironmentVariables, with the comment:

// 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 中:

However the actual logic to set the restriction is in 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权利.您可能可以直接测试受限状态,也可以根据这些信息自己构建一个功能来测试这些条件.

As you can see, it depends on, issetugid, hasRestrictedSegment, and the CS_RESTRICT / SIP entitlements. You might be able to test for restricted status directly, or you could probably construct a function to test for these conditions yourself based on this information.

这篇关于通过bash调用应用程序时dyld_insert_libraries被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 08:00