【发布时间】:2018-12-17 15:42:47
【问题描述】:
背景: 我了解到,出于安全原因,具有 setuid 的父程序不能将 LD_LIBRARY_PATH 作为环境的一部分,因此任何子进程也不会“看到”LD_LIBRARY_PATH。
背景: 我的父程序(请参阅https://github.com/shadow-robot/ethercat_grant/blob/kinetic-devel/src/ethercat_grant.cpp)需要 setuid 来更改子程序的 CAP_NET_RAW 等功能。然而,子程序(在我的控制下,例如这个https://github.com/shadow-robot/ros_ethercat/blob/kinetic-devel/ros_ethercat_loop/src/main.cpp)使用通过 RPATH 找到的库,它们自己需要访问依赖库,而不是在我的控制下,并且只能通过 LD_LIBRARY_PATH 找到(由于 ubuntu bionic @987654323 中新强制执行的 RUNPATH @)。
所以我需要一个解决方法来将 LD_LIBRARY_PATH 传递给子进程。 我认为 execve() 应该会有所帮助,我的问题只在这里。
解决方法: 我 putenv() LD_LIBRARY_PATH=/my/path/ 在父应用程序中,删除权限,然后使用新的环境调用 execve() 。我想这是安全的,因为在 env 中重新添加的 LD_LIBRARY_PATH 仅用作标准用户而不是特权用户。在此处查看代码https://github.com/ubi-agni/ethercat_grant/blob/env_append/src/ethercat_grant.cpp
问题: LD_LIBRARY_PATH 在 execve() 中再次被删除。 [编辑] 如果之前未使用 cap_set_file,它的行为似乎正确(只要在调用 execve 之前删除特权),所以问题是功能和 execve 之间的某种关系 [/EDIT]
研究:我发现了一些关于这种不受欢迎行为的旧报告 http://austingroupbugs.net/view.php?id=922 ,但没有明确解释(在 man ld.so 或其他中)即使 setuid 匹配 seteuid (相同对于组)在删除权限后,execve() 将再次删除 LD_LIBRARY_PATH。
问题:我想知道这种行为仍然是有意的,或者如果我错过了一些 proc/thread 功能,我也应该进行更改,以便子进程不会继承父进程“安全“执行,从而保持我的新环境完好无损? [编辑] 确实似乎与影响子进程的能力有关[/编辑]
谢谢。
【问题讨论】:
-
如果 execve() 与 env variables 参数一起传递,它应该获取变量。这在基本级别应该可以通过 LD_LIBRARY_PATH。