clang 没有停留在 #include "/dev/whatever"
clang not stuck at #include "/dev/whatever"
我在做在线评委代码安全的项目。一个可能的漏洞是当有人上传一段这样的代码时:
#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 忽略所有这些?我怎样才能让 Clang 被 #include
-ing 卡住?
C 标准规定
A preprocessing directive of the form
# include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence [...]. How the places are specified or the header
identified is implementation-defined.
A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the
source file identified by the specified sequence between the "
delimiters. The named source file is searched for in an
implementation-defined manner. If this search is not supported, or if
the search fails, the directive is reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if any)
from the original directive.
(C2011 6.10.2/2-3;已强调)
特别是,绝对不需要 C 实现来将 header 具有绝对路径形式的名称 解释为 绝对路径。这样的 header 名称甚至不在符合标准的编译器必须为其提供唯一映射的名称中。
符合标准的 C 编译器必须记录所有 implementation-defined 行为。 GCC 确实提供了涵盖该领域的文档,但这些文档似乎并未明确说明绝对路径。然而,在我看来,GCC 只使用给定的路径似乎是合理的。 Clang 的行为显然不同,但它没有记录其 implementation-defined 行为(因此在这方面是 non-conforming)。它的输出可能会提供有关它正在做什么的线索。
更新:
Why does Clang ignore all these?
您可以检查其源代码以确定 Clang 正在做什么的细节,但只有 Clang 开发团队可以肯定地告诉您为什么 Clang 是以这种方式实现的。也许它的开发人员预料到您的 hosted-service 用例并有意强化 Clang 以抵抗您描述的那种攻击。
How can I make Clang stuck by #include-ing something?
您已经尝试过的方法似乎是最有可能的。如果它们不起作用,那么可能就没有办法以这种方式破坏 Clang。
创建一个 fifo,并 #include 它。
请注意,这似乎只是停止了 clang;它没有从中读取。
这可能只在 clang 团队看到这个之前有效....
我在做在线评委代码安全的项目。一个可能的漏洞是当有人上传一段这样的代码时:
#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 忽略所有这些?我怎样才能让 Clang 被 #include
-ing 卡住?
C 标准规定
A preprocessing directive of the form
# include <h-char-sequence> new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence [...]. How the places are specified or the header identified is implementation-defined.
A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if any) from the original directive.
(C2011 6.10.2/2-3;已强调)
特别是,绝对不需要 C 实现来将 header 具有绝对路径形式的名称 解释为 绝对路径。这样的 header 名称甚至不在符合标准的编译器必须为其提供唯一映射的名称中。
符合标准的 C 编译器必须记录所有 implementation-defined 行为。 GCC 确实提供了涵盖该领域的文档,但这些文档似乎并未明确说明绝对路径。然而,在我看来,GCC 只使用给定的路径似乎是合理的。 Clang 的行为显然不同,但它没有记录其 implementation-defined 行为(因此在这方面是 non-conforming)。它的输出可能会提供有关它正在做什么的线索。
更新:
Why does Clang ignore all these?
您可以检查其源代码以确定 Clang 正在做什么的细节,但只有 Clang 开发团队可以肯定地告诉您为什么 Clang 是以这种方式实现的。也许它的开发人员预料到您的 hosted-service 用例并有意强化 Clang 以抵抗您描述的那种攻击。
How can I make Clang stuck by #include-ing something?
您已经尝试过的方法似乎是最有可能的。如果它们不起作用,那么可能就没有办法以这种方式破坏 Clang。
创建一个 fifo,并 #include 它。 请注意,这似乎只是停止了 clang;它没有从中读取。 这可能只在 clang 团队看到这个之前有效....