Compiler Fuzzing: How Much Does It Matter?
Marcozzi, Michaël, Qiyi Tang, Alastair F. Donaldson和Cristian Cadar. 《Compiler Fuzzing: How Much Does It Matter?》 Proceedings of the ACM on Programming Languages 3, 期 OOPSLA (2019年10月10日): 1–29. https://doi.org/10.1145/3360581.
Background
编译器模糊测试是一个比较有争议性的话题
-
发现的bug的重要性
在对用于处理非关键软件的编译时,可以忍受一定程度的不可靠性,以换取降低的开发成本,因此有理由质疑编译器模糊处理程序发现的编译器bug的重要性
由开发人员进行的常规编译器测试与最终用户的密集操作相结合,很可能会掩盖严重的错误
-
能否从用户发现的编译器bug来改进编译器的模糊测试
Objectives and Challenges
(a)研究在广泛使用的编译器中发现的编译错误对现实应用程序的编译有多大影响
(b)比较由fuzzer发现的错误和人工发现的错误的影响
Contributions
(1)从三个角度评估错误编译对给定应用程序正确性和可靠性的影响:
- 编译期间(是否运行到出错的编译器代码位置并且触发了bug?)
- 通过生成代码的语法分析(错误对二进制文件的汇编语法有多大影响?)
- 动态分析生成的二进制文件(错误是否导致应用程序运行时行为的明显差异?)
(2)关于成熟编译器中错误编译错误对realworld的影响的首次系统性研究:
- 评估在309个不同的Debian软件包(共1000万行C / C ++)中Clang / LLVM中的45个已修复错误编译bug的影响
- 比较由Fuzzer发现的27个错误的影响与用户在相同的Debian软件包中编译实际代码或通过工具发现的18个错误的影响
Main Findings
fuzzer发现的bug所关联的代码至少会触发一次,并且在编译实际应用程序时会很频繁。几乎一半的错误会造成某些package二进制层面上的差异,这些差异只影响一小部分程序中的函数功能,并且会导致几次测试失败。
关于用户报告的以及还存在的一些bug,作者在进行实验时并没有触发,而且这些bug在正常情况下都很少触发并且导致测试失败。
通过手动分析编译器bug导致的二进制层面的差异发现,这些二进制程序上的差异对应用程序的语义没有影响,或者需要非常特殊的运行环境才能触发执行差异。
Conclusion:
- 高质量、广泛使用与生产环境的编译器中的编译bug很少会影响已部署应用程序的正确性和可靠性
- 通过模糊测试器发现的bug与其他来源的bug具有同等的影响
Fuzzers and Compiler Verification Tools Studied
Csmith:Csmith生成没有未定义或未指定行为的C程序
EMI:提出equivalence modulo inputs测试思想。给定一个程序P和输入x,去查找输入x没有覆盖的程序语句,将这些语句删除生成一系列功能等效于P的新程序,利用这些新程序来测试编译器
Orange3/4:通过C语言的子集来模糊C编译器,主要侧重于测试算术表达式的编译。 Orange3随机生成一个程序,并在生成该程序应计算的精确结果时保持跟踪。相反,Orange4是基于将测试程序转换为等效形式的,如果正确编译,这些形式都可以保证产生相同的输出。转换包括向程序添加语句或将常量扩展为表达式
Yarpgen:通过跟踪程序生成过程中的变量类型,对齐方式和值范围,它可以准确地检测并避免未定义的行为。它还合并了指导随机生成的策略。
Alive
Method & Result
这两部分是对前文中所提到的方法的详细介绍、实验实施以及实验结果。
一句话总结:
这篇文章其实是对编译器测试价值的一个实验评估,通过实验来分析和评估编译器的bug对生成的程序在各个不同层面的影响。
Future work
- 可以复现作者的研究或者对Clang/LLVM之外尤其是成熟度不如这两者的的其他编译器进行类似的评估
- 对编译器bug的分析限制在它们对已编译应用程序的正确性和可靠性的影响上,除开这两者,其他方面比如编译器的bug对生成的程序在效率或者安全性上面会不会产生一些影响,有没有可能利用类似的错误潜在的在应用程序中引入后门程序
- 通过自动化的方式(比如符号执行)判断代码段之间在语义上是否等效。这种方式可能更彻底,并且可以利用Oracle来检测由错误编译引发的运行故障。