slot deposit pulsa slot mahjong slot gacor slot gacor slot gacor resmi slot gacor 2025 slot gacor terpercaya slot gacor 2025 slot gacor hari ini slot gacor hari ini slot gacor hari ini
Google 将空间内存安全功能“改造”到 C++ 上
17611538698
webmaster@21cto.com

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

编程语言 0 841 2024-12-13 08:57:59

图片

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

图片

Google 正在尝试对此采取行动——同时也为充满不安全的遗留代码的世界树立了一个优秀榜样。

Google 研究人员通过实践表明,他们已经能够将空间安全性“改造”到他们的 C++ 代码库中,而且对应用性能的影响非常小。

一篇关于他们研究结果的博客文章引发了更广泛的社区讨论,网上还出现了一些有趣的后续评论,有些人甚至大声质疑这种低影响是否意味着 C++ 代码可以默认包含空间内存安全性。

这也提出了长期存在的假设,可能随着时间的推移而受到挑战的可能性——并且当面临严重问题时,新技术总有可能提供帮助。

安全设计改造


一切始于一篇官方博客,该篇文章描述了 Google 如何通过在其 C++ 代码中添加边界检查来保护其服务器端生产系统,从而提高 Gmail、YouTube、Google 地图甚至 Google 搜索引擎的安全性。


Google 已经是内存安全语言和其他安全编码实践的早期采用者,但全面过渡仍需要数年时间,这意味着他们还需要采取额外措施:“尽可能将安全设计原则改进到我们现有的 C++ 代码库中。”


文章是由高级软件工程师Alex RebertKinuko Yasuda撰写的(他们与 Google 的Max Shavrick合作,后者也是安全基础团队的成员)。文章指出,LLVM 对 C++ 标准库的实现包括几种强化模式,用于发现未定义的行为,从而可以对 C++ 代码进行边界检查


“我们现在已将其作为我们服务器端生产系统的默认设置,”博客文章解释道,同时密切关注其推出情况。


结果数据如下:


  • 该团队发现了 1,000 多个漏洞。(Google 估计,平均每年可以发现 1,000 到 2,000 个漏洞。)

  • Google 还经历了“整个生产过程中基线分段错误率降低 30%”。他们的文章将此归因于更好的代码可靠性和质量:“除了崩溃之外,检查还捕获了原本会表现为不可预测行为或数据损坏的错误。”

  • 它最终还帮助 Google“识别并修复了十多年来潜伏在我们代码中的多个错误。”强化的 C++ 检查“将许多难以诊断的内存损坏转变为即时且易于调试的错误。”

  • 它甚至扰乱了一次内部红队演习,“证明了其在阻止攻击方面的有效性”。

图片

“我错了”


有一个具体结果引起了最多的关注。谷歌的博客报告称,强化libc++“导致我们所有服务的性能平均下降了 0.30%”。(他们甚至强调写道:“是的,只有三分之一个百分点……”)


图片

此帖子得到了谷歌杰出工程师Chandler Carruth的回应,他也是新Carbon 编程语言的创始人和联合负责人。Carruth 写了一篇自己的博客文章,其中第一部分的标题是“边界检查的开销:是我错了。”

“其他人对成本的大量历史报告,加上我自己进行的一些相当随意的实验,让我坚信边界检查不可能便宜到可以默认启用。然而,到目前为止,它们看起来非常实用。”

不幸的是,这种普遍的观念使得高质量的动态安全检查无法进入libc++(和其他 C++ 库),并且最初也无法进入 LLVM。

强化 C ++之路


但是 Carruth 看到基于编译器的检查已进入 Microsoft Visual C++,而“Apple 中推动C++ 中安全缓冲区的 LLVM RFC 的所有人在这里做出了出色的工作,让 LLVM 生态系统(包括 Clang 和 libc++)最终在这个领域拥有了可靠的工具。” 


Carruth 认为另一个因素是内存安全语言开发人员对 LLVM 的贡献更多(因为越来越多的非 C/C++ 语言开始使用它),带来了“一系列稳定而系统的改进”。


回顾过去,Carruth 认为 LLVM 经过了“许多年”的改进,“我认为我们并没有真正注意到临界点何时到来。在那个时候,这些改进结合起来,从根本上降低了这类检查的实际成本,并使其默认且普遍可用。


“这种级别的可用性改变了安全游戏规则,因为我们不再需要在性能或安全性之间做出痛苦的权衡,我们可以同时获得两者。”


Carruth 写道,通过努力,并且编译器继续支持内存安全检查,“我认为我们有机会默认实现空间内存安全,即使在 C 和 C++ 中,即使在性能最受限制的环境中也是如此。”


这就引发了一个问题:现在是否至少也应该考虑其他安全检查(例如引用计数)——即使我们认为这些检查也会对性能产生严重影响。


“我认为有一些令人信服的证据表明,对于较小的系统(手机、笔记本电脑、连接电池的设备),缓存流量和潜在同步开销的成本最多是微不足道的。我认为 Swift 已经提供了强有力的证据,证明只要在优化基础设施上进行一些投资并谨慎实施,引用计数在这些处理器上可以非常高效。”


Google的帖子在 LinkedIn 上引发了不少讨论:


图片

图片

有没有发生优化?


Carruth 还回顾了“让 LLVM 在优化强化方面做得更好”的努力。


他在这里建议,性能敏感的工作负载受益于配置文件引导优化 (PGO),以及“人们系统地构建优化基础设施……将代码的热路径与安全检查的开销隔离开来,并解锁 LLVM 围绕它们开发的所有其他优化技术,以最大限度地降低成本。”


说到谷歌,他们确实承认了这一点和其他提高性能的技巧——然后补充说“即使没有这些先进的技术,边界检查的开销仍然很小。”(谷歌的博客文章反而将低影响归因于强化libc++设计高效的事实——以及编译器可以在优化过程中消除冗余检查的方式。)


然而,当他们发现 LLVM 执行了不必要的检查(这严重影响了性能)时,他们编写了一个修复程序并将其贡献给 LLVM 项目“以与更广泛的 C++ 社区分享好处”。


用户反应


好消息是,Google 的帖子在网络上引起了一些用户积极的反响。


在 Hacker News 上,它引起了 WebAssembly 联合创始人Ben Titzer回应,他还记得 20 年前曾争论过 C++ 中边界检查的必要性。“程序中存在边界检查可以捕获的错误。使其成为一种内置语言,可使其暴露于专门针对边界检查的编译器优化,从而消除许多错误并大大降低动态成本。


“仅在库中启用它们并不一定能暴露所有编译器优化,但这是一个开始。安全检查应该真正内置到语言中。”


另一个回复来自Walter Bright,他创建了替代的 Zortech C++ 编译器。


Bright 也是系统编程语言 D 的创建者,他描述了20 年前 D 语言添加数组边界检查后发生的事情:“这是一个巨大的胜利。”在另一条评论中,Bright回忆起将边界检查设为 D 语言中的默认选项。“为了关闭数组边界,你必须打开一个开关,而且这只发生在标记为 @system 的代码上。


“事实证明,这是正确的举措。”


但也许最积极的回应来自Shane Miller (Rust 基金会的杰出顾问)在 LinkedIn 上发布的呼吁。“很高兴你们没有止步于通过这一举措来获取安全胜利。


“你们掌握的关于识别错误和提高可靠性的数据是极好的参考。”

作者:大雄

评论