我注意到,在我调用 g ++ (甚至 gcc 强大>对于那个问题)使用 -static 选项,二进制文件的链接失败 - 总是由于某些库或其他库未成功找到。因此,我只能生成使用共享库的二进制文件。
这是一个问题,因为我有一种情况,如果没有编写使用Setuid Root权限安装的程序,我无法解决。我需要编写的这个程序将检查环境变量以确保它们没有任何恶意(并且它会以更好的安全而不是抱歉的态度这样做)然后它会降级它的用户ID使用 exec()的形式调用另一个程序之前之前的常规用户。
对环境的这些安全检查将确保其他程序可以在关键环境变量(例如 DYLD_LIBRARY_PATH )未损坏的保证下安全运行。但是这个程序本身可以不在任何这样的保证下运行 - 因为它是执行这项检查的一部分。 第一个的地方。
那么如何保护这个C ++程序免受这样的安全漏洞的影响呢?我的第一个想法是使用 -static 选项编译它 - 但由于这在OS X上不起作用,是否有人有其他想法?
感谢。
答案 0 :(得分:1)
编辑:只要可执行文件是setuid,加载程序就会杀死所有DYLD_ *环境变量。来自the source code for dyld.cpp:
// 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.
[原始答案:]根据this post by Sam Marshall,您可以通过在名为" __ RESTRICT"的二进制标题中添加新的部分,并使用名为" __ restrict"的部分。 。您可以在Xcode中将其添加到"其他链接器标志"中来执行此操作:
-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null
忽略DYLD_LIBRARY_PATH的其他可能方法是将可执行文件设置为setuid或setgid,或使用权利签名。来自the source code for dyld.cpp:
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;
}