paint-brush
AWS Firecracker VMM 的微架构安全性:背景经过@autoencoder
399 讀數
399 讀數

AWS Firecracker VMM 的微架构安全性:背景

太長; 讀書

本研究论文调查了 Firecracker 抵御微架构攻击的安全性。
featured image - AWS Firecracker VMM 的微架构安全性:背景
Auto Encoder: How to Ignore the Signal Noise HackerNoon profile picture
0-item

作者:

(1)Zane Weissman,伍斯特理工学院,美国马萨诸塞州伍斯特市{[email protected]};

(2)Thomas Eisenbarth,德国吕贝克大学 {[email protected]};

(3)Thore Tiemann,德国吕贝克大学{[email protected]};

(4)Berk Sunar,伍斯特理工学院,美国马萨诸塞州伍斯特市{[email protected]}。

链接表

2.背景

2.1 KVM

基于 Linux 内核的虚拟机 (KVM) [29] 提供了现代 CPU 中可用的硬件辅助虚拟化功能(如 Intel VT-x 或 AMD-V)的抽象。为了支持近乎原生的执行,除了现有的内核模式和用户模式外,Linux 内核还添加了客户模式。如果处于 Linux 客户模式,KVM 会使硬件进入硬件虚拟化模式,从而复制 ring 0 和 ring 3 权限。[1]


使用 KVM,I/O 虚拟化主要由创建 VM 的进程(称为 VMM 或虚拟机管理程序)在用户空间中执行,而早期的虚拟机管理程序通常需要单独的虚拟机管理程序进程 [41]。KVM 虚拟机管理程序为每个 VM 客户机提供自己的内存区域,该区域与创建客户机的进程的内存区域分开。这对于从内核空间和用户空间创建的客户机都是如此。每个 VM 都映射到 Linux 主机上的进程,分配给客户机的每个虚拟 CPU 都是该主机进程中的一个线程。VM 的用户空间虚拟机管理程序进程仅在需要特权执行时才对 KVM 进行系统调用,从而最大限度地减少上下文切换并减少 VM 到内核的攻击面。除了推动各种应用程序的性能改进之外,这种设计还允许开发轻量级虚拟机管理程序,这些虚拟机管理程序特别适用于对单个程序进行沙盒处理和支持许多 VM 同时运行的云环境。

2.2 无服务器云计算

一种越来越流行的云计算模型是无服务器计算,其中 CSP 管理运行用户代码的服务器的可扩展性和可用性。无服务器计算的一种实现称为函数即服务 (FaaS)。在此模型中,云用户通过服务提供商的应用程序编程接口 (API) 定义根据需要调用的函数(因此称为“函数即服务”),而 CSP 管理执行用户函数的服务器上的资源分配(因此称为“无服务器计算” - 用户无需管理任何服务器)。同样,容器即服务 (CaaS) 计算按需运行容器、可移植的运行时包。FaaS 和 CaaS 的集中式服务器管理对 CSP 和用户都具有经济吸引力。CSP 可以随心所欲地管理用户的工作负载,优化以降低运营成本,并实施灵活的定价,用户只需支付他们使用的执行时间即可。用户不需要担心服务器基础设施的设计或管理,从而降低了开发成本,并以相对较小且可预测的速度将维护成本外包给CSP。

2.3 MicroVM 和 AWS Firecracker

FaaS 和 CaaS 提供商使用各种系统来管理正在运行的函数和容器。Docker、Podman 和 LXD 等容器系统提供了一种方便且轻量级的方式来在任何环境中打包和运行沙盒应用程序。但是,与用于许多更传统的云计算形式的虚拟机相比,容器提供的隔离性较差,因此安全性也较低。近年来,主要的 CSP 推出了 microVM,它们通过轻量级虚拟化支持传统容器,以提供额外的安全性。[1, 55] KVM 的硬件虚拟化效率和 microVM 的轻量级设计意味着虚拟化、容器化或类似容器的系统中的代码可以运行得几乎与未虚拟化的代码一样快,并且开销与传统容器相当。


Firecracker [1] 是 AWS 开发的微虚拟机,用于将 AWS Lambda FaaS 和 AWS Fargate CaaS 工作负载隔离在单独的虚拟机中。它仅支持 x86 或 ARM Linux-KVM 主机上的 Linux 客户机,并为客户机系统提供有限数量的设备。这些限制使 Firecracker 的代码库大小和正在运行的虚拟机的内存开销非常轻量,并且启动或关闭速度非常快。此外,使用 KVM 减轻了 Firecracker 的要求,因为一些虚拟化功能由内核系统调用处理,主机操作系统将虚拟机作为标准进程进行管理。由于 Firecracker 的代码库很小,用 Rust 编写,因此人们认为它非常安全,尽管早期版本中已经发现了安全漏洞(参见 CVE-2019-18960)。有趣的是,Firecracker 白皮书宣称微架构攻击属于其攻击者模型 [1] 的范围,但除了针对客户机和主机内核的常见安全系统配置建议外,缺乏详细的安全分析或针对微架构攻击的特殊对策。Firecracker 文档确实提供了系统安全建议 [8],其中包括具体的对策列表,我们将在第 2.6.1 节中介绍这些措施。

2.4 Meltdown 和 MDS

2018 年的 Meltdown [32] 攻击表明,通过将推测访问的数据编码到缓存侧信道中,可以跨越安全边界进行泄露。这很快导致了一类类似的攻击,称为微架构数据采样 (MDS),包括 Fallout [14]、Rogue In-flight Data Load (RIDL) [50]、TSX Asynchronous Abort (TAA) [50] 和 Zombieload [46]。这些攻击都遵循相同的一般模式来利用推测执行:


(1)受害者运行处理秘密数据的程序,秘密数据经过缓存或 CPU 缓冲区。


(2)攻击者运行一条专门选择的指令,该指令将导致 CPU 错误地预测需要秘密数据。CPU 将秘密数据转发给攻击者的指令。


(3)转发的秘密数据被用作攻击者有权访问的数组的内存读取索引,从而导致该数组的特定行被缓存。


(4)CPU 完成数据检查并确定秘密数据被错误转发,并将执行状态恢复到转发之前,但缓存的状态不会恢复。 (5)攻击者探测整个数组以查看哪一行被缓存;该行的索引是秘密数据的值。


最初的 Meltdown 漏洞针对的是缓存转发,并允许以这种方式从缓存中存在的任何内存地址提取数据。MDS 攻击针对的是内核微架构中较小且更具体的缓冲区,因此构成了一类相关但不同的攻击,其缓解方式也大不相同。虽然 Meltdown 针对的是更新频率相对较低且在所有内核、线程和进程之间共享的主内存,但 MDS 攻击往往针对内核本地的缓冲区(尽管有时在线程之间共享)并在执行期间更频繁地更新。


2.4.1 基本 MDS 变体。图 1 列出了英特尔 CPU 上已知的主要 MDS 攻击路径以及英特尔和报告这些变体的研究人员为不同变体起的名字。最广泛地说,英特尔根据数据从中推测转发的特定缓冲区对其 CPU 中的 MDS 漏洞进行分类,因为这些缓冲区往往用于许多不同的操作。RIDL MDS 漏洞可分为微架构加载端口数据采样 (MLPDS)(针对从 CPU 的加载端口泄漏的变体)和微架构填充缓冲区数据采样 (MFBDS)(针对从 CPU 的 LFB 泄漏的变体)。同样,英特尔将 Fallout 漏洞称为微架构存储缓冲区数据采样 (MSBDS),因为它涉及存储缓冲区的泄漏。向量寄存器采样 (VRS) 是 MSBDS 的一种变体,它针对通过存储缓冲区时由向量操作处理的数据。VERW 绕过利用了


图 1:英特尔 CPU 上的主要 MDS 攻击路径和变体名称。顶部的蓝色名称是英特尔给出的漏洞名称;底部的红色名称是研究人员给出的名称或报告漏洞的论文名称。并非所有故障类型都适用于所有系统上的所有漏洞 — 推测执行期间的成功转发和编码取决于确切的微架构,包括任何现有的微架构对策,因此对每种已知组合进行分类超出了本文的范围。


微代码修复了 MFBDS,将陈旧且可能保密的数据加载到 LFB 中。泄漏的基本机制是相同的,VERW 旁路可以被视为 MFBDS 的一个特例。L1 数据驱逐采样 (L1DES) 是 MFBDS 的另一个特例,其中从 L1 数据缓存中驱逐的数据会通过 LFB 并容易受到 MDS 攻击。值得注意的是,L1DES 是一种攻击者可以实际触发秘密数据在 CPU 中的存在(通过驱逐它)的情况,而其他 MDS 攻击则直接依赖于访问秘密数据的受害者进程将其带入正确的 CPU 缓冲区。


2.4.2 Medusa。Medusa [37] 是英特尔归类为 MLPDS 变体 [25] 的一类 MDS 攻击。Medusa 漏洞利用了不完善的模式匹配算法,该算法用于推测性地组合英特尔处理器写入组合 (WC) 缓冲区中的存储。英特尔认为 WC 缓冲区是加载端口的一部分,因此英特尔将此漏洞归类为 MLPDS 的一种情况。已知的 Medusa 变体有三种,每种都利用写入组合缓冲区的不同功能来导致推测性泄漏:


缓存索引:故障负载被推测与具有匹配缓存行偏移量的早期负载相结合。


未对齐的存储到加载转发:有效存储后跟依赖加载会触发未对齐内存故障,从而导致来自 WC 的随机数据被转发。


影子 REP MOV :错误的 REP MOV 指令后跟一个依赖加载,从而泄露了不同 REP MOV 的数据。


2.4.3 TSX 异步中止。硬件漏洞 TSX 异步中止 (TAA) [24] 为执行 MDS 攻击提供了一种不同的推测机制。虽然标准 MDS 攻击使用标准推测执行访问受限数据,但 TAA 使用 TSX 实现的原子内存事务。当原子内存事务遇到异步中止时,例如由于另一个进程读取标记为由事务使用的缓存行,或者由于事务遇到故障,事务中的所有操作都会回滚到事务启动前的架构状态。但是,在此回滚期间,事务中已经开始执行的指令可以继续推测执行,就像其他 MDS 攻击的步骤 (2) 和 (3) 一样。TAA 会影响所有支持 TSX 的英特尔处理器,对于不受其他 MDS 攻击影响的某些较新的处理器,必须在软件中实现 MDS 缓解措施或 TAA 特定的缓解措施(例如禁用 TSX)以防范 TAA [24]。


2.4.4 缓解措施。尽管 Meltdown 和 MDS 类漏洞利用的是低级微架构操作,但大多数易受攻击的 CPU 上的微代码固件补丁都可以缓解这些漏洞。


页表隔离。从历史上看,内核页表已包含在用户级进程页表中,以便用户级进程能够以最小的开销对内核进行系统调用。页表隔离(由 Gruss 等人首次提出,称为 KAISER [19])仅将最低限度的必要内核内存映射到用户页表中,并引入仅由内核访问的第二个页表。由于用户进程无法访问内核页表,因此除了一小部分经过专门选择的内核内存之外,对内核内存的所有访问都会在到达 Meltdown 攻击开始的较低级别缓存之前停止。


缓冲区覆盖。针对核心 CPU 缓冲区的 MDS 攻击需要较低级别且更有针对性的防御。英特尔推出了一个微代码更新,当刷新第一级数据 (L1d) 缓存(缓存定时侧信道攻击的常见目标)或运行 VERW 指令时,它会覆盖易受攻击的缓冲区 [25]。然后,内核可以在切换到不受信任的进程时触发缓冲区覆盖,从而防止 MDS 攻击。


缓冲区覆盖缓解措施针对 MDS 攻击的源头,但至少可以说并不完善。启用 SMT 后,进程仍然容易受到同一核心上并发运行线程的攻击(因为两个线程共享易受攻击的缓冲区,而活动进程实际上并未在任一线程上发生变化),此外,在最初的缓冲区覆盖微码更新后不久,RIDL 团队发现在某些 Skylake CPU 上,缓冲区被陈旧且可能敏感的数据覆盖 [50],即使启用缓解措施并禁用 SMT,仍然容易受到攻击。还有一些处理器容易受到 TAA 攻击,但不会受到非 TAA MDS 攻击,并且没有收到缓冲区覆盖微码更新,因此需要完全禁用 TSX 以防止 MDS 攻击 [20, 24]。

2.5 幽灵


2018 年,Jan Horn 和 Paul Kocher [30] 独立报告了第一个 Spectre 变体。此后,人们发现了许多不同的 Spectre 变体 [22、30、31、33] 和子变体 [10、13、16、28、52]。Spectre 攻击使 CPU 推测性地访问架构上无法访问的内存,并将数据泄漏到架构状态中。因此,所有 Spectre 变体都由三个组件组成 [27]:


第一个组件是推测执行的 Spectre 小工具。Spectre 变体通常按其利用的错误预测来源进行区分。例如,条件直接分支的结果由模式历史表 (PHT) 预测。PHT 的错误预测可能导致加载和存储指令的推测边界检查绕过 [13、28、30]。间接跳转的分支目标由分支目标缓冲区 (BTB) 预测。如果攻击者可以影响 BTB 错误预测的结果,那么推测性返回导向编程攻击是可能的 [10、13、16、30]。对于由返回堆栈缓冲区 (RSB) 提供的预测也是如此,它在执行返回指令期间预测返回地址 [13、31、33]。最近的结果表明,如果 RSB 下溢,一些现代 CPU 会使用 BTB 进行返回地址预测 [52]。Spectre 攻击的另一个来源是存储到加载依赖关系的预测。如果错误地预测加载不依赖于先前的存储,它会推测性地执行陈旧数据,这可能会导致推测性存储绕过 [22]。所有这些小工具默认情况下都不可利用,但依赖于现在讨论的另外两个组件。


第二个要素是攻击者如何控制上述小工具的输入。攻击者可能能够直接通过用户输入、文件内容、网络数据包或其他架构机制来定义小工具的输入值。另一方面,攻击者可能能够通过加载值注入 [12] 或浮点值注入 [42] 暂时将数据注入小工具。如果攻击者能够影响在推测窗口期间访问或执行哪些数据或指令,他们就能够成功控制小工具的输入。


第三个组件是隐蔽通道,用于将推测的微架构状态转换为架构状态,从而将推测访问的数据泄露到持久环境中。如果受害者代码根据推测访问的秘密数据 [30] 执行瞬时内存访问,则缓存隐蔽通道 [39、40、54] 适用。如果秘密被推测访问并加载到内核缓冲区中,攻击者可以依赖基于 MDS 的通道 [14、46、50] 将泄露的数据瞬时传输到攻击者线程,然后通过缓存隐蔽通道等将数据传输到架构状态。最后但并非最不重要的是,如果受害者根据秘密数据执行代码,攻击者可以通过观察端口争用来了解秘密 [3、11、18、43、44]。


2.5.1 缓解措施。已经开发了许多应对措施来缓解各种 Spectre 变体。如果删除三个必需组件之一,则特定 Spectre 变体将被有效禁用。无法控制 Spectre 小工具输入的攻击者不太可能成功发起攻击。如果没有用于将推测状态转换为架构状态的隐蔽通道,情况也是如此。但由于这通常很难保证,因此 Spectre 应对措施主要侧重于阻止错误预测。在关键代码段之前插入 lfence 指令可禁用超出此点的推测执行,因此可以用作通用应对措施。但由于其高性能开销,因此开发了更具体的应对措施。Spectre-BTB 应对措施包括 Retpoline [48] 和微代码更新,如 IBRS、STIBP 或 IBPB [23]。可以通过在 RSB 中填充值以覆盖恶意条目并防止 RSB 下溢或安装 IBRS 微代码更新来缓解 Spectre-RSB 和 Spectre-BTB-via-RSB。可以通过 SSBD 微代码更新缓解 Spectre-STL [23]。阻止攻击者篡改共享分支预测缓冲区的另一种激进方法是禁用 SMT。禁用 SMT 可以有效地在并发租户之间划分分支预测硬件资源,但代价是性能大幅下降。

2.6 AWS 的隔离模型

Firecracker 专为无服务器和容器应用程序 [1] 构建,目前由 AWS 的 Fargate CaaS 和 Lambda FaaS 使用。在这两种服务模型中,Firecracker 都是支持每个单独的 Fargate 任务或 Lambda 事件的主要隔离系统。这两种服务模型也设计用于运行大量相对较小且短暂的任务。AWS 列出了最终成为 Firecracker 的隔离系统的设计要求,如下所示:


隔离性:多个功能在同一硬件上运行时必须是安全的,并防止权限提升、信息泄露、隐蔽通道和其他风险。


开销和密度:必须能够在一台机器上运行数千个功能,并且尽量减少浪费。


性能:功能必须与本机运行类似。性能还必须一致,并且与同一硬件上的邻居的行为隔离。


兼容性:Lambda 允许函数包含任意 Linux 二进制文件和库。必须在不更改代码或重新编译的情况下支持这些文件和库。


快速切换:必须能够快速启动新功能和清理旧功能。


软分配:必须能够过度使用 CPU、内存和其他资源,每个功能仅消耗其所需的资源,而不是其有权使用的资源。[1]


我们对隔离要求特别感兴趣,并强调微架构攻击已声明为 Firecracker 威胁模型的范畴。AWS 公共 Firecracker Git 存储库中的“设计”页面详细说明了隔离模型,并提供了一个有用的图表,我们在图 2 中重现了该图表。该图表主要涉及防止特权升级。最外层的保护是 jailer,它使用容器隔离技术来限制 Firecracker 在运行 VMM 和其他管理组件时对主机内核的访问


图 2:AWS 在 Firecracker GitHub 存储库中的设计文档中提供了此威胁遏制图 [6]。在此模型中,jailer 为 Firecracker 的 VMM、API、实例元数据服务 (IMDS)(所有这些都在主机用户空间中运行)和客户工作负载(在虚拟机内运行)提供类似容器的保护。VM 将客户的工作负载隔离在客户机中,确保它仅与主机的预定元素(在用户空间和内核空间中)直接交互。


Firecracker 的进程被划分为主机用户空间中单个进程的线程。在 Firecracker 进程中,用户的工作负载在其他线程上运行。工作负载线程执行虚拟机的客户操作系统以及客户机中运行的任何程序。在虚拟机客户机中运行用户代码会将其与主机的直接交互限制为与 KVM 和 Firecracker 管理线程的某些部分的预先安排的交互。因此,从主机内核的角度来看,VMM 和 VM(包括用户代码)在同一个进程中运行。这就是 AWS 声明每个 VM 都驻留在单个进程中的原因。但是,由于 VM 是通过硬件虚拟化技术隔离的,因此用户的代码、客户机内核和 VMM 在不同的地址空间中运行。因此,客户机的代码无法在架构上或暂时访问 VMM 或客户机内核内存地址,因为它们未映射到客户的地址空间中。剩余的微架构攻击面仅限于 MDS 攻击(忽略地址空间边界,从 CPU 内部缓冲区泄露信息)和 Spectre 攻击(攻击者操纵其他进程的分支预测来自我泄露信息)。


图 2 中未显示,但对 AWS 威胁模型同样重要的是,在共享硬件时,功能彼此隔离,尤其是考虑到软分配要求。除了破坏主机内核可能会危及任何客户机的安全之外,针对主机硬件的微架构攻击也可能直接威胁用户代码。由于单个 Firecracker 进程包含运行具有用户功能的虚拟机所需的所有线程,因此主机操作系统可以简单地执行软分配 [1]。这意味着在虚拟机隔离之上还安装了标准 Linux 进程隔离系统。


2.6.1 Firecracker 安全建议。Firecracker文档还建议采取以下预防措施来防范微架构侧通道攻击 [8]:


• 禁用 SMT


• 启用内核页表隔离


• 禁用内核 kame-page 合并


• 使用带有 Spectre-BTB 缓解措施的编译内核(例如 x86 上的 IBRS 和 IBPB)


• 验证 Spectre-PHT 缓解措施


• 启用 L1TF 缓解 • 启用 Spectre-STL 缓解


• 利用 Rowhammer 缓解措施来使用内存


• 禁用交换或使用安全交换



[1] 虚拟化的ring 0和ring 3是实现近本机代码执行的核心原因之一。