shadowsocks / ShadowsocksX-NG

Next Generation of ShadowsocksX
GNU General Public License v3.0
32.34k stars 7.94k forks source link

dyld: Library not loaded: @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib 错误 #1100

Closed mokitoo closed 5 years ago

mokitoo commented 5 years ago

Describe the bug 最新分支上编译出来的小飞机,打开后,ss-local没有正常启动,ss-local的日志如下所示

dyld: Library not loaded: @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib Referenced from: /Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local Reason: unsafe use of relative rpath @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib in /Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local with restricted binary

但是这种情况电脑开机过一会儿,重新打开小飞机,又自动恢复正常了(ss-local正常启动了)

System and Shadowsocksx-NG version: (please complete the following information):

ss-local.log

Logs cat ss-local.log dyld: Library not loaded: @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib Referenced from: /Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local Reason: unsafe use of relative rpath @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib in /Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local with restricted binary

mokitoo commented 5 years ago

$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist

看了下这个文件, `

DYLD_LIBRARY_PATH
            <string>/Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/:/Users/buffer/Library/Application Support/ShadowsocksX-NG/plugins/</string>
    </dict>`

里面既然已经指定了寻找动态库的地址 DYLD_LIBRARY_PATH, 那么为啥会去 @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib 这里找libev.4.dylib这个动态库呢。。。。? @qiuyuzhou 大佬,求指教

mokitoo commented 5 years ago

@timothyqiu 看大佬好像回复过相关问题,不知道能否帮忙看看,我这边不是手动去执行ss-local的 而是通过打开GUI来完成的,那么按照道理正常来说,这些动态库应该是自动会去上面指定的目录--DYLD_LIBRARY_PATH 里面去寻找

timothyqiu commented 5 years ago

@Buffer2Disk

What that error message means is not "library not found", but "I won't try to load that library because it's not safe". Maybe you triggered some sort of protection mechanism of macOS loader.

FYI, the @@HOMEBREW_PREFIX@@ thing is part of the library name embedded in the executable. You can use otool -L or otool -l to verify:

$ otool -L '/Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local'
/Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
        @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib (compatibility version 5.0.0, current version 5.0.0)
        @@HOMEBREW_PREFIX@@/opt/udns/lib/libudns.0.dylib (compatibility version 0.0.0, current version 0.0.0)
        @@HOMEBREW_PREFIX@@/opt/libsodium/lib/libsodium.18.dylib (compatibility version 21.0.0, current version 21.0.0)
        @@HOMEBREW_PREFIX@@/opt/mbedtls/lib/libmbedcrypto.0.dylib (compatibility version 0.0.0, current version 2.4.2)
        @@HOMEBREW_PREFIX@@/opt/pcre/lib/libpcre.1.dylib (compatibility version 4.0.0, current version 4.8.0)
mokitoo commented 5 years ago

@timothyqiu 你说的对,我昨天查了下,macos 10.1 以后好像是有个默认的保护机制,不允许去访问一些敏感的目录,所以作者的设计思路才会是把这些要使用的动态库都放在一个允许被访问的目录下: /Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest 然后通过设置DYLD_LIBRARY_PATH的路径,让ss-local 从上面的地址去获取动态库。

所以现在的问题是,为什么没有使用DYLD_LIBRARY_PATH设置的路径来寻找需要的动态库,或者说可能是因为DYLD_LIBRARY_PATH没找到对应的动态库,导致转而去寻找 @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib 这样的路径。 因为mac存在这样的保护机制,所以 @@HOMEBREW_PREFIX@@这么查找肯定会失败。

我查看过$HOME/Library/LaunchAgents/com.qiuyuzhou.shadowsocksX-NG.local.plist文件,路径设置的都没啥没问题,launchctl 的服务也删除重启过

我这边的otool信息如下, otool -L '/Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local' /Users/buffer/Library/Application Support/ShadowsocksX-NG/ss-local-latest/ss-local: /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1) @@HOMEBREW_PREFIX@@/opt/libev/lib/libev.4.dylib (compatibility version 5.0.0, current version 5.0.0) @@HOMEBREW_PREFIX@@/opt/c-ares/lib/libcares.2.dylib (compatibility version 5.0.0, current version 5.0.0) @@HOMEBREW_PREFIX@@/opt/libsodium/lib/libsodium.23.dylib (compatibility version 25.0.0, current version 25.0.0) @@HOMEBREW_PREFIX@@/opt/mbedtls/lib/libmbedcrypto.2.dylib (compatibility version 2.0.0, current version 2.9.0) @@HOMEBREW_PREFIX@@/opt/pcre/lib/libpcre.1.dylib (compatibility version 4.0.0, current version 4.10.0)

mokitoo commented 5 years ago

@timothyqiu @qiuyuzhou

找到问题原因了,是因为开启了 hardened runtime 后,没有去指定开启权限,导致一些权限默认被禁止掉了 这里被禁掉的权限就是 DYLD Environment Variables 这个

具体文档如下 https://developer.apple.com/documentation/security/hardened_runtime_entitlements

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

但是同时也发现了1.8.2版本的一个bug LaunchAgentUtils.swift 里面 InstallSSLocal 函数 判断ss-local文件是否存在的那个代码有问题, 具体的问题就是文件里面写的那个ss-local版本不对,导致路径错误,从而每次判断该文件都不存在 最终导致每次启动ssx-ng时,都会去重复安装 ss-local

lucasff commented 5 years ago

That's a great debugging. Thanks @Buffer2Disk, I can't since ever use Shadowsocks on my Mac because of this issue. Could you try to submit a patch (pull request)? Then I try to compile it and see how it goes.

mokitoo commented 5 years ago

That's a great debugging. Thanks @Buffer2Disk, I can't since ever use Shadowsocks on my Mac because of this issue. Could you try to submit a patch (pull request)? Then I try to compile it and see how it goes.

1.Tag 1.8.2 signed at 2018-09-25 had not enabled hardened runtime as default , so it won't occurs such a problem about disable DYLD Environment Variables. But if you want build and enable hardened runtime by yourself , you need to specify entitlements. Here is my entitlements below :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.automation.apple-events</key>
       <true/>
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
       <true/>
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
 <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
 <key>com.apple.security.cs.disable-executable-page-protection</key>
    <true/>
 <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
 <key>com.apple.security.device.camera</key>
    <true/>
 <key>com.apple.security.personal-information.calendars</key>
    <true/>
 <key>com.apple.security.personal-information.photos-library</key>
    <true/>
</dict>
</plist>

2.The bug about install ss-local will not affect usage. just a small fix about modify ss-local version to 3.2.0 in LaunchAgentUtils.swift

999 888

3.Submit a PR is ok , but author seems haven't online for quite a long time

lucasff commented 5 years ago

@Buffer2Disk I was thinking in forking this repo, merging all open pull requests, make some tests and checks and then publish as 1.9.0, and then link here so other people can download or maybe compile themselves. Shadowsocks for mac feels leftover now.

jearton commented 2 years ago

这是由于在软件运行时,有携带额外的环境变量,需要添加该环境变量,才能正常执行 ss-local。正确步骤为:

  1. 查看软件运行时的环境变量

    cd ~/Library/LaunchAgents
    cat com.qiuyuzhou.shadowsocksX-NG.local.plist

    找到DYLD_LIBRARY_PATH这个环境变量

  2. 添加环境变量

    export DYLD_LIBRARY_PATH=上一步找到环境变量值
  3. 再进入 ss-local 目录下,执行 ss-local 脚本

    cd ~/Library/Application Support/ShadowsocksX-NG/ss-local-3.2.5
    ./ss-local -h

这样就不会报错了