【问题标题】:Determine which binary will run via execlp in advance预先确定哪个二进制文件将通过 execlp 运行
【发布时间】:2017-01-27 05:38:38
【问题描述】:

编辑#1


到目前为止,“可能的重复”是不是重复的。他们在$PATH 中测试$FILE 的存在,而不是提供第一个有效结果的完整路径;最佳答案使用 命令行命令,而不是纯

原始问题


在所有 exec 系列函数中,有一些函数会进行 $PATH 查找,而不需要执行二进制文件的绝对路径。

来自man exec

execlp()、execvp() 和 execvpe() 函数复制操作 如果指定了在搜索可执行文件时的 shell 文件名不包含斜杠 (/) 特点。在 PATH 环境变量中指定的以冒号分隔的目录路径名列表中查找该文件。如果 此变量未定义,路径 list 默认为当前目录,后跟 confstr(_CS_PATH) 返回的目录列表。 (这个 confstr(3) call 通常返回值 “/bin:/usr/bin”。)

是否有一种简单直接的方法来测试第一个“执行的完整路径”将评估为什么,而无需手动遍历 $PATH 环境变量中的所有元素,并将二进制名称附加到路径的尽头?我想使用“事实上的标准”方法来估计要运行的二进制文件,而不是重写过去可能已经实施过多次的任务。

我知道这不能保证,因为有人可能会通过错误的脚本、TOCTOU 攻击等使该检查无效。我只需要一个合适的近似值来进行测试。

谢谢。

【问题讨论】:

  • 你为什么要问?实际用例是什么?请编辑您的问题以激发它。
  • @BasileStarynkevitch 我想知道什么程序将(可能)提前执行以进行测试。
  • 对安全敏感的应用程序应该做的测试(在我偏执的意见中)是首先找到要执行的实际二进制文件(然后使用确切的完整路径),然后检查文件的所有权,目录和所有父目录,两次。这个想法是验证没有不受信任的用户对它们中的任何一个具有写访问权;第二遍是验证与第一遍(诱饵和转换)相比没有任何变化。 UID 0、GID 0(“root”)始终是受信任的,任何其他受信任的帐户都依赖于应用程序。

标签: bash c c linux exec system-calls execl


【解决方案1】:

是否有一种简单直接的方法来测试第一个“执行的完整路径”将评估为什么,而无需手动遍历 $PATH 环境变量中的所有元素

不,您需要遍历 $PATH(即 C 代码中的 getenv("PATH"))。一些(非标准)库提供了一种方法来做到这一点,但它真的很简单,你不应该打扰。您可以使用strchr(3) 来查找冒号: 的“下一个”出现,因此对该循环进行编码非常简单。正如Jonathan Leffler 评论的那样,它们是微妙的(例如权限、挂起符号链接、一些其他 进程将一些新的可执行文件添加到$PATH 中提到的目录),但大多数程序会忽略它们。

真正相关的是运行execvp 之前的PATH 值。实际上,它是启动程序时PATH 的值(因为外部进程无法更改它)。您只需要确保您的程序不会更改PATH,这很可能(极端情况和困难的情况是相同process 的其他线程)更改PATH 环境变量putenv(3)setenv(3))。

实践中,PATH 不会改变(除非有一些代码明确地改变它)。即使您使用专有库并且没有时间检查其源代码,您也可以期望 PATH 在您的流程执行期间在实践中保持不变。

如果您需要一些更精确的东西,并假设您在程序名称上使用 execp 函数,这些函数是编译时常量,或者至少在程序初始化读取一些配置文件后是常量,您可以执行许多 shell 正在执行的操作: “缓存”将PATH 搜索到某个哈希表的结果,并在其上使用execve。尽管如此,您还是无法避免某些other 进程在PATH 中提到的目录中添加或删除文件的问题;但大多数程序并不关心(并且在编写时隐含假设这不会发生,或者会通知您的程序:以 zshrehash 内置函数为例)。

但您总是需要测试exec(包括execlp(3)execve(2))和fork 函数的失败。即使PATH 未更改且其中提及的目录和文件未更改,它们也可能因多种原因而失败。

【讨论】:

  • 解析 PATH 值有一些棘手的问题。形式上,如果第一个字符是冒号,或者最后一个字符是冒号,或者 PATH 中有两个相邻的冒号,那么目录名称是(隐式)'.'(点,当前目录)。还有其他复杂的因素:检查文件的权限,ACL(这可能会隐藏用户或组实际上有权限),也许检查目录的权限,但如果你可以检查文件的权限,你通常没事。
  • @JonathanLeffler:原则上你是完全正确的。在实践中,人们通常不在乎。
  • 谢谢。这比与此问题相关的“可能重复”提供的信息要多得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
相关资源
最近更新 更多