当前位置: 首页 > 科技观察

谷歌正在寻求提高C++内存安全性_0

时间:2023-03-19 18:43:56 科技观察

谷歌Chrome安全团队表示一直致力于提高Chrome浏览器的内存安全性;最近,团队正在研究利用堆扫描技术来提高C++的内存安全性。虽然从内存安全的角度来看,Rust可能在当下更受大众欢迎。但Chrome安全团队认为,尽管人们对内存安全保证比C++更强的其他语言感兴趣,但在可预见的未来,像Chromium这样的大型代码库将使用C++。考虑到这一点,Chrome工程师找到了使C++更安全的方法,以减少与内存相关的安全漏洞,如缓冲区溢出和释放后使用(UAF)。据统计,这些漏洞占所有软件安全漏洞的70%。auto*foo=newFoo();deletefoo;//foo指向的内存位置不再代表//Foo对象,因为该对象已被删除(释放)。foo->Process();如上例,当应用程序使用的内存返回给底层系统,但指针指向一个过时的对象时,就会发生一种称为悬空指针的情况,并且通过它进行的任何访问都会导致UAF访问。充其量,此类错误会导致明确定义的崩溃;在最坏的情况下,它们会造成破坏,并可能被恶意行为者利用。在较大的代码库中,UAF通常很难发现,因为对象的所有权在不同组件之间转移。这个问题非常普遍,以至于直到现在,工业界和学术界都经常提出针对它的缓解策略。虽然在Chrome中使用C++没有什么不同,但大多数高严重性安全漏洞都是UAF问题。在最近发布的Chrome102中,修复了一个严重的UAF问题,8个高危漏洞中有6个是UAF。为了解决这个问题,Chrome使用了各种技术;包括C++智能指针(如MiraclePtr)、编译器中的静态分析、动态工具(如C++sanitizers)、代码模糊器,以及一个名为Oilpan的工具C++垃圾收集器。Oilpan、MiraclePtr和基于智能指针的解决方案需要采用大量应用程序代码。此外,谷歌还探索了另一种方法:内存隔离(memoryquarantine)。基本思想是将明确释放的内存放入隔离区,并且仅在满足某些安全条件时才使其可用。Chrome安全团队在一篇博文中总结了在Chrome中尝试隔离和堆扫描的过程。它的工作原理是,隔离和堆扫描的时间安全背后的主要思想是避免重复使用内存,直到证明没有更多(悬空)指针指向它。为避免更改C++用户代码或其语义,拦截提供new和delete的内存分配器。当调用delete时,内存实际上被隔离,不能再用于应用程序的后续新调用。“在某些时候会触发堆扫描,扫描整个堆,就像垃圾收集器一样,寻找对隔离内存块的引用。没有从常规应用程序内存中获取引用的块被移回分配器,在那里它们可以被重新用于后续分配。”据介绍,谷歌的堆扫描由一组名为StarScan(简称*Scan)的算法组成。他们将*Scan应用于渲染器进程的非托管部分,使用Speedometer2评估性能影响,并尝试了不同版本的*Scan。测试结果表明*Scan的基本版本导致8%的内存回归。“所有这些开销从何而来?不出所料,堆扫描极受内存限制,因为扫描线程必须遍历并检查对整个用户内存的引用”。经过各种优化后,Speedometer2回归从8%降低到2%。此外,内存消耗测量表明,在渲染过程中进行扫描可将内存消耗减少约12%。MTE(MemoryTaggingExtension)是ARMv8.5A架构上的新扩展,有助于检测软件内存使用中的错误;这些错误可以是空间错误(如越界访问),也可以是时间错误(use-after-free)。Google获得了一些支持MTE的实际硬件,并在渲染器过程中重新进行了实验。结果表明,Speedometer2中的内存回归约为2%,尽管MTE和内存归零会带来一些成本。实验还表明,在MTE之上添加*Scan没有可衡量的成本。Chrome安全团队得出结论,C++可用于编写高性能应用程序,但要以安全为代价。硬件内存标记可以修复C++的一些安全漏洞,同时保持高性能。“我们期待在未来看到更广泛地采用硬件内存标记,并建议在硬件内存标记之上使用*Scan来修复C++中的临时内存安全。所使用的MTE硬件和*Scan的实现都是原型,我们预计以仍有性能优化的空间。”本文转自OSCHINA文章标题:谷歌正在寻求提高C++内存安全文章地址:https://www.oschina.net/news/198093/google-c-memory-safety