An Armful of CHERIs
今天,Arm宣布首款支持Morello原型架构的硅芯片现已限量供应演示板,并从今日起向行业合作伙伴发货以供测试。Morello是CHERI扩展的首个高性能实现。CHERI在硬件级别提供细粒度的空间内存安全性。我们之前已完成对QEMU上CHERI软件栈原型的 security review,现在将有机会在快速的当代超标量处理器上更深入地评估CHERI。
Portmeirion项目是Microsoft Research的Confidential Computing Group与Microsoft Security Response Center之间的合作,探索硬件-软件协同设计以提升安全性,并将与这些系统合作。
与许多其他 proposed 内存安全技术不同,CHERI(通过设计)不依赖于秘密。这意味着它确定性地缓解漏洞类别,而不是以高概率检测它们。概率性缓解历史上并未显示出持久性,因为攻击者找到泄露秘密的方法,将低概率攻击转化为高概率攻击。攻击者可以通过泄露秘密来绕过任何依赖于秘密的缓解措施,并且如果能够减少秘密的熵,则可能以高概率绕过它。CHERI的确定性方面也意味着它可以作为更高级别安全抽象的基础构建块。
CHERI改变抽象机器
CHERI始于2010年由SRI International和剑桥大学联合进行的研究工作,由DARPA Clean-slate design of Resilient, Adaptive and Secure Hosts (CRASH) program资助。该计划要求参与者愿意重新思考硬件/软件栈中的所有内容以提高安全性。
在CHERI的情况下,这是以自PDP-11以来主流硬件未曾做过的方式改变硬件暴露的用户可见抽象机器。后续机器添加了MMU用于虚拟内存,但未添加进程内内存隔离机制。在进程内,这些机器保留了地址只是整数因此可以从 thin air materialized 的抽象。虚拟化扩展允许多个操作系统实例以类似方式隔离,但每个实例在进程内保留相同的抽象。在进程中运行的任何代码段都可以构造一个整数值,如果该整数对应于进程地址空间中的有效位置,则它可以访问该位置的内存。攻击者每天利用这些弱点——对当前硬件架构至关重要。
CHERI改变了这一点。每个加载或存储指令以及每个指令获取必须由架构能力授权。加载和存储指令将能力作为基础而不是整数地址。能力既标识地址又授予对内存范围的访问权限(包括权限,如读、写或执行)。ISA提供用于限制能力上权利的操作(例如,减少边界或移除权限),但没有机制可以在不从更强大的能力开始的情况下增加权利(能力单调性)。这包括将能力存储到内存中,它们受(不可寻址的)标签位保护,任何尝试覆盖内存中能力部分或全部的操作都会清除标签位并使能力无效。
CHERI权限与MMU组合。能力授予的权利相对于地址空间,并受进程和VM隔离以及CHERI限制的约束。
有许多不同的方式使用CHERI,就像有许多方式使用传统MMU一样。在最粗粒度,您可以使用仅两个能力寄存器:程序计数器能力(PCC)和默认数据能力(DDC)。这些分别限制相对跳转和采用整数地址的跳转范围,以及传统(非CHERI)加载和存储指令。在此模式下,您可以在进程地址空间中创建轻量级carveouts作为隔离沙箱,为现有本机代码提供类似WebAssembly的隔离。
在最细粒度(称为“纯能力ABI”或“CheriABI”),诸如C或C++等语言实现中的每个指针都降级为能力。当您通过mmap、VirtualAlloc或类似方式从OS请求更多地址空间时,OS将提供授予该内存权利的新能力。当malloc或operator new返回新对象时,它将细分这些能力之一并提供访问 precisely one object 的指针。系统中的任何机制都无法将其转换为指向另一个对象的指针。在这两个极端之间有各种可能性。
CheriABI提供完整的对象粒度(以及 potentially 字段或数组元素粒度)空间内存安全性。与其他现有缓解措施组合,我们 prior analysis 显示,这将确定性地防止2019年提交给MSRC的约43%的漏洞。 compartmentalization 可以进一步限制攻击者利用其中一些漏洞可能造成的损害。我们与剑桥大学和SRI正在进行的关于CHERI堆时间安全性的工作将将此增加到近70%。
拥有可用于测试的硬件是该计划的重大进步,因为行业可以开始测试这在现实世界应用程序中如何工作,以及开始解决它面临的一些挑战,例如软件兼容性。在纯能力ABI中,指针增长到128位。它们可以存储在声明为intptr_t的变量中,但不能存储在long或其他整数类型中,并且它们不能从整数值 materialized。所有这一切意味着C/C++软件最多是源兼容的(需要重新编译),并且通常需要至少一些小的源代码修改,至少如果您想要任何安全好处。您也可以在CHERI系统上运行非CHERI软件,就像您可以在大多数64位处理器上运行32位软件一样。
这导致了一个引导问题:没有人愿意修改他们的代码(可能以侵入性方式)来支持没有工业牵引力的架构,也没有人愿意发布没有软件的ISA。UKRI的Digital Security by Design (DSbD) challenge 是通过构建现实原型并资助软件开发来打破这种僵局的大规模政府和行业投资。Morello CPU是四核、2.5GHz修改的Arm Neoverse N1,一个当代超标量服务器核心。在此之前,最先进的CHERI实现是CHERI版本的Toooba,它可以在FPGA中以50MHz运行在双核配置中,并且在微架构上大致相当于90年代中期的CPU。尽管Toooba是一项重大成就,但它不够快或不够现实,无法大规模启动复杂软件栈或运行详细性能分析。
改进时间安全性
CHERI未在架构中直接实现时间安全性。它确实提供了软件实现所需的架构构建块。具体来说,软件可以使用标签位准确识别内存中的每个指针,并可以依赖单调性保证确保每个指针可以映射到它创建时指向的分配。
这些保证类似于垃圾收集环境中发现的保证。对于C和C++代码,我们不希望添加垃圾收集,因为抽象机器已经有显式释放,并且C++代码依赖于析构函数在确定性点运行。相反,我们希望添加撤销,逻辑对偶。垃圾收集确保对象持续到所有指向它们的指针都消失。撤销确保当对象消失时(或至少在内存在重用之前)指向对象的指针被删除。这与Microsoft的Project Snowflake为.NET中的手动内存管理提供的抽象保证相同:任何尝试访问指向已释放对象的指针的尝试保证要么访问旧对象(而不是在同一空间中分配的任何新对象),要么陷入陷阱。
一个朴素的实现将简单地暂停程序执行并遍历地址空间的16字节块。对于它找到的每个能力,它将查询分配器以查看指针对象是否已被释放,如果是,则将能力清零。这将工作,只要您愿意定期忍受多秒的暂停时间。不幸的是,大多数软件不是。
有几种技巧可以加速这一点。首先,大多数内存不包含任何指针。文本、图像或其他数据的大缓冲区通常构成堆分配的80%左右。MMU中的能力脏位允许撤销扫描仅识别已存储一个或多个能力的页面,消除其他部分。这显著减少了暂停时间,但仍然意味着您有与堆大小成比例的暂停时间。
Cornucopia通过使用MMU强制存储屏障和 mostly 并发运行改进了这一点。每次页面在撤销器在后台运行时存储能力时,它可能具有更多需要撤销的无效能力。最终,未扫描页面集足够小,撤销器可以暂停程序并扫描剩余部分,使用非常类似于VM实时迁移的技术。
通过Morello,我们与Arm和剑桥大学合作添加了功能,使Cornucopia的后续工作能够允许读取屏障替换写入屏障和更短的同步阶段。每个Morello核心在机器特定寄存器(MSR)中有一个一位字段,用作生成计数器。如果此位与页表的相应位匹配并且从页面加载有效能力,则Morello交付陷阱。这意味着,在经过一个小的同步阶段,该阶段在每个核心上切换MSR位并扫描每个运行线程的寄存器文件后,运行程序维护不变式,即其寄存器文件中的任何能力在撤销传递开始时有效。我们相信我们可以在此基础上构建更高效的时间安全性设计。
我们也对这类设计如何与另一种Arm内存安全技术组合感兴趣:Arm Memory Tagging Extension (MTE)。MTE最初设计用于大规模检测导致漏洞的错误,但我们 primarily 对其作为 enforcement 技术感兴趣。MTE在设计空间中与CHERI处于非常不同的位置。它旨在与现有代码接近100%二进制兼容。这通过要求它支持可能在一个上下文中安全但在另一个上下文中不安全的习惯用法(例如将long转换为指针)来施加它可以强制执行的安全性的上限。它将4位“颜色”与每个16字节内存块关联,并将相同颜色嵌入指针的顶部位中,提供锁和钥匙机制,其中指针中的颜色与内存中的不匹配由硬件检测。与CHERI不同,MTE的安全性依赖于秘密(颜色)并且不防止指针注入。MTE可以确定性地缓解线性溢出,但如果攻击者可以泄露特定地址的颜色(例如,通过读取现有指针或使用推测侧通道披露它),那么他们可以注入MTE将视为有效的指针。
如果您两者都有会发生什么?CHERI防止受保护的操作,因此可以限制重新着色内存的权利到内存分配器(或任何给定地址空间块的所有者)并防止指针伪造,包括防止重新着色指针。CHERI还提供边界检查,移除MTE要求两个相邻分配必须具有不同颜色(以保护 against 线性溢出)。在支持两者的系统中,在释放时立即重新着色内存保护 against use after free,包括允许分配器安全地在释放的对象中存储元数据。通过使用Morello的性能数据,我们将能够探索研究问题,例如这是否允许我们更高效地实现CHERI撤销。
有了CHERI,我们还需要安全语言吗?
如果事实证明我们可以为C/C++提供完整的空间和时间内存安全性,我们还需要安全编程语言吗?我们不为C++获得与Rust或C#相同的保证吗?
C和C++的内存安全性通过添加对未定义行为类别的限制来工作。C说任何在传递给free()后使用指针的行为是未定义的。这是诸如C之类的语言可以说的一切,因为没有比“某些未指定的坏事可能发生”更强的定义在所有C目标上可行。访问数组末尾也是如此。在具有软件时间安全性解决方案的CHERI系统上,我们可以保证您不会访问错误的对象。我们不能保证您会获得陷阱(编译器可能完全省略加载或存储,如果它证明它是未定义行为),但我们可以保证您要么获得陷阱,要么做不违反内存安全的事情。
您如何处理那个陷阱?有足够多的错误恢复代码中的漏洞来自此类错误,以至于您唯一能做的安全事情可能是杀死触发陷阱的组件。相反,安全语言通过构造防止您执行会触发陷阱的操作。尽管CHERI C++和C#的安全属性可能相似,但可用性属性将非常不同。CHERI C++中导致陷阱的一些错误类别在C#中要么导致编译失败,要么根本不可能表达。
因为CHERI C/C++依赖于定义未定义行为来添加安全性,它无法对现有的已定义但危险的行为做任何事情,而不破坏进一步的软件语义,这将需要更多软件更改。CHERI C仍然允许联合或任意指针转换,可能导致类型混淆错误。它强制执行1位类型安全保证:您不能意外地将非指针数据解释为指针,但您仍然可以将指向一种类型的指针与指向另一种类型的指针混淆。同样,这种错误在安全语言中通过构造防止。当代类型安全语言通过构造防止大类错误,而CHERI内存保护防止利用其中一些错误类别。有数十亿行C和C++代码广泛使用,CHERI的强源级兼容性提供了一条实现高性能内存安全目标的路径,而不需要从头重写。
关于隔离性呢?
CHERI的许多焦点在C/C++内存安全性上。这仍然是最常见的安全漏洞来源,因此这种焦点有意义。CHERI旨在强制执行两个重要的安全原则:
- 最小权限原则
- intentional use 原则
最小权限意味着程序、组件等仅以它需要的最小权利集运行。在内存安全环境中,这意味着它只能访问它应该能够使用的对象集(并且只能写入它应该能够写入的对象)。 intentionality 意味着任何权利的使用应该是显式的。再次,在内存安全环境中,这意味着您应该只通过您期望指向它的指针访问对象。如果您尝试使用MMU保护来隔离组件,那么您将获得第一个但不是第二个:组件只能访问映射到其地址空间的对象,但指针算术错误可能允许它意外修改它持有权利但不打算修改的对象。
这些原则扩展到 just 内存安全之外。Web浏览器使用多个进程以较低权限运行处理不受信任数据的组件。Windows使用 hypervisor 隔离组件(“安全内核”)保护秘密免受潜在内核危害。还有其他此类隔离系统的例子,但它们非常少,即使最成功的通常也只有少数隔离。编写 aggressively 隔离软件有两个障碍:
- MMU隔离进程昂贵,如果您有太多,TLB抖动主导性能。
- C/C++假设单一权限域,不提供任何推理隔离的工具。
CHERI解决第一个。创建隔离在最简单情况下可以像malloc()调用一样便宜。CHERI系统中的隔离只是从能力寄存器可达内存的传递闭包。在类似C的语言中,这难以推理。考虑以下C示例:
|
|
在这个简单示例中,您可能破坏了隔离隔离。如果l1在隔离中但l2不在(或在不同的隔离中),那么您刚刚传递了隔离一个允许它访问它不应该使用的内存的指针。如果l2在隔离中但l1不在,那么您创建了一个列表,其中受信任代码将跟随攻击者控制的指针。
避免此类问题是Project Verona的目标之一,这是一个Microsoft Research项目,属于Portmeirion umbrella,旨在构建具有一流隔离支持的语言。我们可以在各种机制上实现此模型,例如基于MMU的隔离或软件故障隔离,但期望CHERI将提供比当前商品硬件上的任何东西更好的性能和可扩展性。
Morello计划的目标
我们期待能够在Morello上原型化Verona的隔离,以及探索更快的时间安全性、内存安全代码的整体性能、最小TCB系统中的隔离等等。如果Morello计划能够证明CHERI满足现实世界使用的性能目标,那么它将是安全性的游戏改变者,确定性地防止空间安全漏洞和(带有软件支持)堆时间安全错误, dramatically 减少可被利用的错误集,除了拒绝服务之外。
任何安全技术如果性能开销超过5%就很少达到广泛采用,如果开销超过10%则 incredibly 罕见。Morello将为我们提供关于仅空间安全性的CHERI C、堆时间安全性和隔离的性能影响的更好数据。Morello提供了服务器级微架构开销的上限:它是一个 minimally 修改的Arm Neoverse N1,因此不代表从一开始就设计支持CHERI的核心和内存子系统。通常,向后兼容的解决方案也比不兼容的解决方案有优势,我们希望Morello计划将提供更多关于支持包含遗留软件的非常大生态系统的CHERI的努力的数据。
Saar Amar, Nicolas Joly – Microsoft Security Response Center (MSRC) _David Chisnall, Manuel Costa, Sylvan Clebsch, Wes Filardo, Boris Köpf, Robert Norton-Wright, Matthew Parkinson – Microsoft Research (MSR)