写点什么

谷歌将空间内存安全功能“改造”到 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:3211345

评论 1 条评论

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

关于Appium2.0

IT蜗壳-Tango

三周年连更

专家共话:存力一体成“东数西算”全场景利器

脑极体

算力

解决使用宝塔安装的swoole扩展,运行项目出现的3个常见问题

北桥苏

php 游戏开发 swoole

数据采集在现代科技中的应用与挑战

数据堂

dart-sass与node-sass的区别以及使用dart-sass可能会出现的问题

不叫猫先生

CSS SASS 三周年连更

新技术层出不穷,程序员到底该走哪条路|社区征文

阿泽🧸

职业规划 三周年征文

关于使用ElascticSearch的两个小技巧

北桥苏

php elasticsearch

大数据如何助力营销(2)用户画像

MobTech袤博科技

自学C4D,不要错过这些教程

Finovy Cloud

2023开源之夏|来自MatrixOne社区的邀请函

MatrixOrigin

MatrixOrigin MatrixOne 开源之夏

敏态开发在大兴机场数字化转型中的实践

明道云

手势识别:解放双手,开启智能时代

数据堂

白鹭游戏引擎网络棋牌搭建步骤

北桥苏

php 游戏开发 白鹭引擎

详细版Jmeter随机参数的接口并发测试总结

北桥苏

Jmeter

大模型应用产品落地!提升理财师展业效果

中关村科金

PHP通过Modbus Tcp实时获取设备数据

北桥苏

物联网 PLC Modbus Tcp

MatrixOne Layout 设计解读

MatrixOrigin

分布式数据库 MatrixOrigin MatrixOne

websocket测试工具的环境搭建与使用

北桥苏

Jmeter webscoket

浅谈一下ThinkPHP5.1实现事务嵌套的特性

北桥苏

php thinkphp 事务回滚

BitKeep逆势崛起:千万用户的信任,终点还未到来

小哈区块

ihateniggers:针对Python开发者的Windows远控木马分析

墨菲安全

墨菲安全 软件供应链安全 投毒分析

涅槃重生,BitKeep如何闯出千万用户新起点

BlockChain先知

BitKeep逆势崛起:千万用户的信任,终点还未到来

西柚子

ES数据没了?谁动了我的数据?

极限实验室

elasticsearch 数据误删 数据丢失

PoseiSwap:合规、隐私与支持更广泛的资产

BlockChain先知

ImageBind 横跨六种数据模式,用向量统一 AI 语言

Zilliz

Zilliz AIGC 向量数据库 Towhee imagebind

涅槃重生,BitKeep如何闯出千万用户新起点

股市老人

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