Macos 在Mac OS X上编译不受库重定向影响的二进制文件

Macos 在Mac OS X上编译不受库重定向影响的二进制文件,macos,g++,static-libraries,static-linking,setuid,Macos,G++,Static Libraries,Static Linking,Setuid,我注意到,在Mac OS X上(目前我运行的是Yosemite,但在早期版本的OS X上我遇到了同样的问题),每当我使用-static选项调用g++(或者甚至是gcc)时,二进制文件的链接失败——总是由于找不到某个库或另一个库而失败。因此,我只能生成使用共享库的二进制文件 这是一个问题,因为如果不编写一个使用Setuid Root权限安装的程序,我就无法解决这种情况。我需要编写的这个程序将检查环境变量,以确保它们没有恶意(它将以更好的安全态度而不是抱歉态度进行检查),然后在使用exec()形式调

我注意到,在Mac OS X上(目前我运行的是Yosemite,但在早期版本的OS X上我遇到了同样的问题),每当我使用-static选项调用g++(或者甚至是gcc)时,二进制文件的链接失败——总是由于找不到某个库或另一个库而失败。因此,我只能生成使用共享库的二进制文件

这是一个问题,因为如果不编写一个使用Setuid Root权限安装的程序,我就无法解决这种情况。我需要编写的这个程序将检查环境变量,以确保它们没有恶意(它将以更好的安全态度而不是抱歉态度进行检查),然后在使用exec()形式调用另一个程序之前,将其用户ID降级为普通用户的ID

这些环境安全检查将确保其他程序能够在关键环境变量(如DYLD\u LIBRARY\u PATH)未损坏的情况下安全运行。但是这个程序本身不能在任何这样的保证下运行——因为首先执行这个检查是它工作的一部分

如何保护这个C++程序不受这样的安全漏洞的影响?我的第一个想法是使用-static选项编译它——但既然这在OSX上不起作用,有人有其他想法吗


谢谢。

编辑:只要可执行文件是setuid,加载程序就会终止所有DYLD_*环境变量。发件人:

[原始答案:]根据,您可以通过在名为“\uuu RESTRICT”的二进制头中添加一个名为“\uu RESTRICT”的节来完成此操作。您可以在Xcode中通过将其添加到“其他链接器标志”来完成此操作:

忽略DYLD_LIBRARY_PATH的其他可能方法是将可执行文件设置为setuid或setgid,或使用权限进行签名。发件人:


我不太清楚如何将这个答案中第一个选项中指定的模糊建议转化为行动。我试图按照您的建议去做(假设我理解正确),但收到了以下警告消息——我不确定如何准确地验证所需的结果是否发生。@Sophia_ES错误消息相当不清楚,但我认为问题是您需要在链接器选项的各个部分之间使用逗号,而不是空格。看起来你也在使用GNU编译器,这个选项可能只有苹果基于叮当声的链接器才支持。但是,首先试试逗号,这可能就是所需要的。好吧——这次它没有发出任何吱吱声——如果我现在可以验证是否达到了预期的结果。哦---我注意到您提到,如果可执行文件是setuid或setgid,那么DYLD_LIBRARY_PATH也将被忽略。你是说当我将可执行文件的权限设置为setuid时,我所担心的安全问题会自动得到解决,而苹果已经解决了我所担心的安全问题?@Sophia_ES D'oh!是的,我对你最初的问题中提到setuid的那一部分感到困惑。虽然如果你觉得有妄想症,添加_RESTRICT/_RESTRICT也不会有任何伤害。
// 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.
-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null
dyld::log("dyld: DYLD_ environment variables being ignored because ");
switch (sRestrictedReason) {
    case restrictedNot:
        break;
    case restrictedBySetGUid:
        dyld::log("main executable (%s) is setuid or setgid\n", sExecPath);
        break;
    case restrictedBySegment:
        dyld::log("main executable (%s) has __RESTRICT/__restrict section\n", sExecPath);
        break;
    case restrictedByEntitlements:
        dyld::log("main executable (%s) is code signed with entitlements\n", sExecPath);
        break;
}