文章摘要
文章讨论了Clang编译器在C和C++程序安全性和可靠性方面的改进提议。当前的安全机制分散且文档不全,使用不便。作者建议整合这些机制,形成一个统一的“加固模式”,以提升代码的安全性和易用性。
文章总结
标题:[RFC] 编译器的加固模式 - Clang 前端 - LLVM 讨论论坛
主要内容:
本文是由多位开发者联合提出的关于在Clang编译器中引入“加固模式”的提案。该模式旨在通过统一现有的安全机制,简化用户提升C和C++程序安全性的过程。
背景: C和C++程序的安全性问题一直是生态系统中的重要议题。尽管相关标准组织(如WG21和WG14)在努力改进语言的安全性,但标准的制定速度和范围有限。因此,编译器实现需要成为推动安全性改进的主要力量。Clang已经提供了多种机制来帮助用户提升代码的安全性,但这些机制分散在不同的实现中,文档不完善,使用起来也不够方便。
用户期望: 在加固模式下,用户需要明确的是,编译器可能会在版本更新时破坏现有代码,这是该模式的一个特性,而不是错误。虽然我们仍然希望尽量减少误报,但在安全性优先的情况下,编译器可能会拒绝一些正确但可疑的代码。
GCC的先例:
GCC已经引入了-fhardened模式,启用了多个功能标志和预定义宏。Clang可以借鉴GCC的做法,但不建议完全复制GCC的实现,因为两者在行为上已有差异,且统一实现难度较大。
目标:
加固模式的目标是自动启用一系列-f、-m、-D和-W标志,用户无需手动配置。具体包括:
- 默认启用-ftrivial-auto-var-init、-fPIE、-fcf-protection等-f标志。
- 默认启用-mspeculative-load-hardening、-mlvi-hardening等-m标志。
- 默认启用-Wall、-Wextra、-Werror=return-type等-W标志。
- 启用标准库的加固模式。
- 预定义_FORTIFY_SOURCE、_GLIBCXX_ASSERTIONS等宏。
- 要求用户指定明确的语言标准模式。
- 拒绝编译C89或C++98等被认为不安全的旧语言标准。
- 传递启用ASLR等链接器标志。
提案:
提出了几种实现加固模式的方式:
1. 配置文件:通过--config=hardened启用,维护简单且下游可自定义。
2. 新驱动模式:通过新驱动模式重置用户期望,但可能难以集成到现有构建系统中。
3. 正交标志:使用-fhardened、-mhardened和-Whardened分别指定语言、机器和诊断标志,用户可选择性启用。
4. 单一标志:使用-fhardened等单一标志启用所有加固选项,但需注意与GCC的兼容性问题。
决策: 目前正在寻求社区的高层指导,以确定加固模式的具体实现方式。一旦社区支持该模式,将提出具体的实现方案和初始功能集。
总结: 该提案旨在通过引入加固模式,简化用户提升C和C++程序安全性的过程,同时明确用户期望,避免与GCC的完全兼容性要求。
评论总结
评论内容总结:
关于C++社区对兼容性的态度
- 观点:C++社区过于重视向后兼容性,可能导致新特性难以推广。
- 论据:用户dilawar指出,代码在编译器版本间不兼容被视为特性而非缺陷,但大多数包维护者可能不会接受这种变化。
- 引用:“your code breaking between compiler releases is a feature, not a bug.”
- 引用:“Most package maintainers are not going to like it a bit.”
关于边界检查的性能与重要性
- 观点:边界检查的性能开销已显著降低,是代码加固的重要组成部分。
- 论据:用户wyldfire引用Carruth的文章,指出边界检查的开销仅为0.3%,且是代码加固的关键部分。
- 引用:“0.3% for bounds checks in all the standard library types!”
- 引用:“There's more to the hardening story than just bounds checks. But it's a big part IMO.”
关于在LLVM中引入安全访问指令的建议
- 观点:通过在LLVM IR中引入安全访问指令,可能是一种更简单的解决方案。
- 论据:用户another_twist建议分三个阶段更新LLVM,以支持安全访问指令。
- 引用:“Maybe an easier way out is to add safe access instructions to LLVM itself.”
- 引用:“Its an IR after all, it should be possible to do a 3 phase update.”
关于禁用全局检查开关的建议
- 观点:长期来看,应禁用全局检查开关,仅在函数级别允许关闭检查。
- 论据:用户ajb认为当前机制不够完善,建议通过函数属性实现更精细的控制。
- 引用:“it might be best to disable the ability to switch off checks using command line flags.”
- 引用:“we really need to be able to do it in a function attribute.”