写点什么

谷歌将空间内存安全功能“改造”到 C++ 上

  • 2025-01-26
    北京
  • 本文字数:2782 字

    阅读完需:约 9 分钟

大小:1.34M时长:07:49
谷歌将空间内存安全功能“改造”到C++上

本文最初发布于 THENEWSTACK。



在分析了从 2014 年 7 月 15 日到 2023 年 12 月 14 日近 10 年的 CVE 后,谷歌研究人员计算得出,在 C++中,至少 40%的安全漏洞空间内存漏洞(如越界写入内存)有关。



 (查看大图)

 

不过,谷歌正在努力解决这一问题,同时为这个充满不安全遗留代码的世界树立榜样。

 

谷歌研究人员表示,他们能够将空间安全 “加装 ”到 C++ 代码库中,而且对性能的影响非常非常小。网上有一篇关于他们研究成果的博文,引发了更为广泛的讨论,其中不乏一些有趣的跟帖,有人甚至大声质疑,这种低影响是否意味着 C++代码可以默认包含空间内存安全特性。

 

该文还提出了一种可能性,即一些已经存在很长时间的假设可能会随着时间的推移而受到挑战——当面临的问题比较严重时,或许可以尝试引入新技术。

改进安全设计

这一切都源于一篇博文,该文描述了谷歌如何通过在 C++代码中添加边界检查来保护其服务器端生产系统,从而提高 Gmail、YouTube、谷歌地图甚至谷歌搜索引擎的安全性。谷歌是内存安全语言和其他安全编码实践的早期采用者,但全面过渡往往需要数年时间。也就是说,他们还需要额外做一些工作: “尽可能地在现有 C++代码库中改用安全设计原则"。

 

该博文由资深软件工程师Alex RebertKinuko Yasuda(与谷歌的Max Shavrick合作,后者也是安全基础团队的成员)撰写。该文首先指出,C++标准库的 LLVM 实现中包括几种用于发现未定义行为的加固模式,从而可以对 C++代码进行边界检查

 

该文解释说:”[我们]现在已将其作为服务器端生产系统的默认设置,同时密切监控上线情况。“

 

结果如何?

  • 该团队发现了 1000 多个 Bug。(据谷歌估计,平均每年发现的 Bug 可增加到 1000 至 2000 个)。

  • 谷歌 “整个生产环境的基线分段故障率降低了 30%”。在博文中,他们将此归功于更好的代码可靠性和质量: “除了崩溃之外,检查还发现了一些错误。这些错误可能会表现为不可预测的行为或损坏数据"。

  • 最终,它还帮助谷歌 “发现并修复了多个在代码中潜伏了十多年的 Bug”。经过加固的 C++检查 “将许多难以诊断的内存损坏转化为即时且易于调试的错误”。

  • 它甚至还瓦解了内部的一次红队演习,“证明了它在挫败漏洞利用方面的有效性”。



 (查看大图)

 

“我错了”

其中有一项结果最引人关注。谷歌的博文称,加固libc++“对我们的服务平均造成了 0.30%的性能影响”。

C++中的边界检查:有人问,0.3%的开销是否属实?这不仅仅是一个基准测试结果,我们是通过 Google-Wide profiling 得到的这个结果,我们通过它获得了来自 DC 的实时洞察。这也让我们大吃一惊,因为那比我们预想的要少得多。

https://t.co/zBUvoYzGi1 https://t.co/7NAWBuxdtP

— Kinuko Yasuda (@kinu) 2024年11月16日

 

谷歌杰出工程师Chandler Carruth回应了他们的博文。他也是新兴编程语言Carbon的创始人和联合牵头人。Carruth 撰写了一篇博文,其中第一节的标题就是 "边界检查的开销:我错了"。

 

“其他人关于成本的一些历史报告,再加上我自己的一些简单实验,让我坚定地认为,边界检查的成本不可能低到可以默认启用的程度。然而,到目前为止,它们看起来确实非常低。“

 

遗憾的是,这种普遍的看法使得高质量的动态安全检查没有出现在 libc++及其他 C++库中,最初也没有出现在 LLVM 中。

C 的加固之路

但 Carruth 看到,Microsoft Visual C++引入了基于编译器的检查,而 “在这里,苹果公司所有推动在C++中实现安全缓冲区的人都做了一项了不起的工作,让 LLVM 生态系统(包括 Clang 和 libc++)最终在这一领域拥有了一个可靠的工具”。Carruth 认为,另一个因素是内存安全语言开发人员为 LLVM 做出了更多的贡献(因为更多的非 C/C++语言开始使用 LLVM),从而带来了 “一系列稳定而系统化的改进”。

 

回首过去,Carruth 认为,虽然 LLVM 经过了多年的改进,但"我们并没有真正注意到什么时候已经达到了一个临界点。在那一刻,所有改进一起从根本上降低了此类检查的实际成本,使其在默认情况下就普遍适用。“

 

“这种水平的可用性改变了安全游戏的规则,因为我们不用再在性能或安全性之间做出痛苦的权衡取舍,我们可以两者兼得。“

 

Carruth 用粗体字写道:"我认为,通过努力,借助编译器对内存安全检查的持续支持,我们确实有机会默认实现空间内存安全,即使是在 C 和 C++中,即使是在性能最受限制的环境中。”

 

这就提出了一个问题:现在是否应该考虑下参考计数等其他安全检查——即使我们认为这些检查会带来令人望而却步的性能影响。

 

“我认为,有足够的证明表明,对于比较小的系统(手机、笔记本电脑、其他用电池的东西),缓存流量和潜在同步开销的成本即使再大也微不足道。我认为,Swift 已经提供了强有力的证据,只要在优化基础设施上投入一些资金并认真实施,参考计数就能够在这些处理器上实现极高的效率。”

 

当然,谷歌的博文也在 LinkedIn 上引发了不少讨论:



 (查看大图)

 


 (查看大图)

 

是否需要优化?

Carruth 还回顾了为了“让 LLVM 在优化加固方面做得更好”所作出的努力。他认为,性能敏感型工作负载得益于配置文件引导优化(或 PGO),以及“人们系统性地构建优化基础设施......将代码的热门路径与安全检查的开销隔离开来,并释放了 LLVM 围绕它们所开发的所有其他优化技术,最大限度地降低了它们的成本”。

 

至于谷歌,他们的博文确实承认了这一点以及其他提高性能的技巧,但也补充说:"即使没有这些先进技术,边界检查的开销仍然微乎其微。(谷歌的博文将这种低影响归因于加固后的libc++的高效设计,以及编译器在优化过程中消除冗余检查的方式)。

 

不过,当发现 LLVM 在执行一项不必要的检查(并且对性能有很大影响)时,他们编写了一个修复程序,并将其贡献给了 LLVM 项目,“以便与广大的 C++社区分享这项改进带来的好处”。

各方反应

谷歌的博文在网络上引发了一些积极的反响。在 Hacker News 上,WebAssembly 联合创始人Ben Titzer对此作出了回应,他还记得 20 年前关于 C++中边界检查必要性的争论。”程序中存在边界检查能捕捉到的 Bug。将其作为一种内置特性,编译器就会对其进行专门针对边界检查的优化,这样可以消除许多 Bug,并大大降低动态成本。“

 

“仅仅在库中打开安全检查并不一定能实现所有的编译器优化,但这只是一个开始。安全检查应该真正地内置于语言中"。

 

另一个回应来自Walter Bright,他创建了另一种编译器 Zortech C++。Bright 也是系统编程语言 D 的创建者。他描述了 20 年前 D 引入数组边界检查后发生的事情: “这是一个巨大的胜利“。在另一条评论中,Bright回忆了如何使边界检查成为 D 语言的默认选项。

 

“事实证明,这是正确的选择。”

 

Rust 基金会杰出顾问Shane Miller发表在 LinkedIn 上的回应可能是最积极的,“很高兴你们没有止步于通过这一举措获得安全方面的胜利。“

 

“你们在识别 Bug 和提高可靠性方面所掌握的数据是一个很好的参考"。

 

声明:本文为 InfoQ 翻译,未经许可禁止转载。

 

原文链接:https://thenewstack.io/google-retrofits-spatial-memory-safety-onto-c/

2025-01-26 11:3211434

评论 1 条评论

发布
用户头像
最好集成到语法里
2025-01-28 10:50 · 北京
回复
没有更多了

亮相2024亚马逊云科技re:Invent全球大会,伊克罗德信息荣获中国区年度创新合作伙伴奖

伊克罗德信息科技

知乎 PB 级别 TiDB 数据库集群管控实践

PingCAP

k8s #TiDB TiDB Operator

掌握DevEco Studio这一功能,高效实现ArkTS与C++胶水代码

轻口味

c++ ide 鸿蒙 HarmonyOS HarmonyOS NEXT

今日分享 | 带你领略可视化设计之美

inBuilder低代码平台

设计 可视化 可视化设计

支持全量&增量迁移!YashanDB增量迁移实现原理解读

YashanDB

数据库 yashandb

【YashanDB知识库】删除用户组后,yasql不能免密登录问题

YashanDB

数据库 yashandb

【YashanDB知识库】崖山有哪些内存参数,Share Pool各个参数之间有什么关系

YashanDB

数据库 yashandb

网络设备日志接入观测云最佳实践

观测云

日志 网络设备

印记2024 | 20个“关键词”解码2024大型企业数智化

用友BIP

零代码 国产替代 用友BIP 中企出海 YonGPT

【YashanDB知识库】数据库一主一备部署及一主两备部署时,主备手动切换方法及自动切换配置

YashanDB

数据库 yashandb

5分钟入门微信小游戏开发(二)

扬_帆_起_航

小游戏开发

Python 安装和依赖管理指南:Conda 与 Pip

敲代码不忘补水

Python 开发语言 计算机科学与技术 科学 Miniconda

直播预告:OpenAI 开始拥抱 RTC!为什么 LLM+RTC 才是多模态 AI 的未来?丨RTE Dev Talk

RTE开发者社区

使用 PyCharm 新建 Python 项目详解

敲代码不忘补水

Python pycharm 计算机科学与技术 科学 Miniconda

监控报警服务RAM授权

DashVector

数据库 向量检索 大模型

如何构建成功的财务规划团队?

智达方通

企业管理 全面预算 预算管理 财务规划

OpenAI Realtime API 升级,集成 WebRTC 且降价 60%;豆包发布视觉理解模型,实时语音模型也将上线

RTE开发者社区

线程池异常处理的 5 中方式

FunTester

【YashanDB知识库】GBK库,生僻字插入nvarchar2字段后乱码问题

YashanDB

数据库 yashandb

HarmonyOS Next开发工具DevEco Studio介绍:ASan与TSan检测根治你的C++恐惧症

轻口味

鸿蒙 HarmonyOS DevEco Studio HarmonyOS NEXT

谷歌将空间内存安全功能“改造”到C++上_编程语言_David Cassel_InfoQ精选文章