2

我正在从事在线法官的代码安全项目。一个可能的漏洞是当有人上传一段这样的代码时:

#include "/dev/stdin"
#include "/proc/self/fd/0"
#include <stdio.h>
// Other legitimate code

我正在尝试重现它。使用 编译时gcc foo.c,gcc 会卡住并从终端读取,直到 EOF (Ctrl-D) 符合预期。当我clang foo.c,好吧,什么也没发生。Clang 的行为就像线条从未存在过一样。然后我尝试了这些代码:

#include "/dev/zero"
#include "/dev/random"
#include "/dev/ram"

仍然没有运气。为什么 Clang 忽略所有这些?如何通过#include-ing 使 Clang 卡住?

4

2 回答 2

3

C标准规定

形式的预处理指令

# include <h-char-sequence> new-line

在一系列实现定义的位置中搜索由指定序列唯一标识的标头 [...]。如何指定位置或标识的标头是实现定义的。

形式的预处理指令

# include "q-char-sequence" new-line

导致将该指令替换为由 " 分隔符之间的指定序列标识的源文件的全部内容。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者搜索失败, 该指令被重新处理,就好像它读取

# include <h-char-sequence> new-line

具有与原始指令相同的包含序列(包括 > 字符,如果有的话)。

C2011 6.10.2/2-3;强调添加)

特别是,C 实现绝不需要将具有绝对路径形式的标头名称解释绝对路径。此类标头名称甚至不在符合标准的编译器必须为其提供唯一映射的标头名称中。

符合标准的 C 编译器必须记录所有实现定义的行为。GCC 确实提供了涵盖该领域的文档,但这些文档似乎没有明确解决绝对路径。然而,对我来说,GCC 只使用给定的路径似乎是合理的。Clang 的行为显然不同,但它没有记录其实现定义的行为(因此在这方面不符合标准)。它的输出可能会提供有关它在做什么的线索。

更新:

为什么 Clang 忽略所有这些?

您可以检查它的源代码以确定 Clang 正在做什么的详细信息,但只有 Clang 开发团队可以肯定地告诉您为什么Clang 以这种方式实现。也许它的开发人员预料到了您的托管服务用例,并故意强化 Clang 以抵御您描述的那种攻击。

我怎样才能让 Clang 被 #include-ing 卡住?

您已经尝试过的方法似乎最有可能。如果它们不起作用,那么可能没有办法以这种方式破坏 Clang。

于 2017-12-14T16:42:01.287 回答
2

制作一个fifo,并#include它。请注意,这似乎只是停止铿锵声;它不会从中读取。这可能只有在 clang 团队看到这一点之前才有效....

于 2017-12-14T21:45:57.153 回答