使用以前版本的编译器是否可以防止代码注入?

时间:2014-03-27 07:55:02

标签: c++ c compiler-construction compilation

我想知道今天的现代编译器如MS cc,gcc,clang,icc,更新的版本是否使用相同编译器的当前版本构建?

因为这种风险当然:
http://scienceblogs.com/goodmath/2007/04/15/strange-loops-dennis-ritchie-a/
http://c2.com/cgi/wiki?TheKenThompsonHack

我确信每个人都参与了上述编译器'开发人员知道这个问题,代码由自身的早期版本注入编译器并以无形方式传播。

现在真正的问题,实际上并不是后门之一,但更多关于代码生成的正确性不是吗?如果构建链中某处某些变态扭曲是由纯错误引入的,那么今天的编译器会生成错误的代码,即使编译器的源代码看起来不错,因为Ken Thompson的缺陷也是如此?

因此,如果他们是自己建造的,他们如何保护自己?

2 个答案:

答案 0 :(得分:25)

  

我想知道今天的现代编译器如MS cc,gcc,clang,icc,更新版本是否使用相同编译器的当前版本构建?

Roslyn C#编译器可以自行构建;事实上,它是它自己最好的测试用例之一。当然,它不能在第一天甚至第100天这样做;它是使用以前版本的C#编译器构建的,该编译器是用C ++编写的。

  

如果构建链中某处某些变态扭曲是由纯错误引入的,那么今天的编译器会生成错误的代码,即使编译器的源代码看起来没问题

这是一个严重的问题。

您可以在自建构建编译器中查找错误的一种有趣方法如下:调用原始的非自构建编译器Alpha。使用Alpha构建新的源代码以生成Beta。然后让Beta构建源代码以生成Gamma。然后让Gamma构建源代码以生成Delta。如果为Gamma和Delta生成的二进制文件存在显着差异,则可能存在问题。在给定相同输入的情况下,Beta和Gamma应具有相同的输出。 (C#特别不保证两次编译相同的代码会产生完全相同的二进制文件,因此您必须小心确保您的测试足够复杂以考虑到这一点。)

降低此风险的方式当然与减轻与坏工具相关的任何风险的方式相同:您将各种版本的编译器工具检入存储库,以便您可以回滚到以前的已知良好版本你应该需要编译器。并且你对编译器进行了大量测试。

答案 1 :(得分:5)

一般来说,对于用自己语言实现的编译器,答案是“是”#39;用自己构建编译器是正确性的最佳测试之一。连续运行应该继续生成相同的二进制文件。 ' GC'例如,它是使用四阶段引导程序构建的。

当然,某些语言不能用于编译器编写。

编辑应该明确的是,这个答案是在实质性问题出现时发布的;编译器是用自己以前的版本构建的吗?"它随后被改变了。