MTE 实现详解,第三部分:内核

访问原始链接 Google 翻译

作者:Mark Brand,Project Zero

背景

2018年,ARM在其架构v8.5a版本中提出了一种硬件实现的标记内存方案,称为MTE(内存标记扩展)。

在第一部分中,我们讨论了在我们能够接触到的硬件上测试MTE的技术(和实现)限制。在第二部分中,我们讨论了这些限制对各种用户态上下文中使用MTE构建的缓解措施的影响。本文将基于我们已知的信息,探讨MTE在内核上下文中作为缓解措施的有效性。

回顾一下,基于内存标记的缓解措施存在两类关键的绕过技术:

  1. 已知标记绕过 - 通常,标记值的保密性是内存标记作为缓解措施有效性的关键。标记保密性的破坏允许攻击者直接或间接地确保其无效的内存访问具有正确的标记,从而无法被检测到。
  2. 未知标记绕过 - 实现的限制可能意味着,即使攻击者执行了可能被检测到的标记不正确的内存访问,仍然有机会利用漏洞。

MTE强制执行有两种主要模式:

  1. 同步模式(sync-MTE) - 标记检查失败会导致指令退休时产生硬件故障。这意味着无效读取的结果和无效写入的影响在架构上应该是不可见的。
  2. 异步模式(async-MTE) - 标记检查失败不会直接导致故障。无效读取的结果和无效写入的影响在架构上是可见的,故障会在错误指令执行后的某个时间点,以每CPU标志的形式传递。

自Spectre漏洞以来,很明显,将标准的内存标记方法用作"硬概率缓解措施"1通常是不可能的——在任何攻击者可以构建推测性侧信道的上下文中,已知标记绕过都是一个必须考虑的根本弱点。

内核特有的问题

在内核上下文中,使用MTE设计稳健的缓解措施存在一些额外的复杂因素。从稳定性的角度来看,在内核标记检查失败时强制触发panic可能被认为是有问题的——但我们认为,这对于任何基于异步(或非对称)MTE模式的缓解措施都是至关重要的。以下是我们认为难以系统解决的一些问题:

  1. 与第二部分中讨论的Chrome渲染器场景类似,我们预计在存在CPU推测性侧信道的情况下,保证内核内存的保密性将持续存在问题。这从根本上限制了基于MTE的缓解措施在内核中对抗本地攻击者的有效性,使得已知标记绕过极有可能发生。
  2. 当前内核实现需要启用TCR_ELx.TCMA1。这意味着任何标记为0b1111的指针都可以在不进行标记检查的情况下被解引用。这是出于多种原因所必需的——例如,内核中有许多地方需要从物理地址或struct page中的偏移量生成可解引用的指针。这使得攻击者能够可靠地伪造指向任何地址的指针,这在漏洞利用过程中是一个显著优势。
  3. [仅ASYNC模式] 很可能需要直接访问标记故障状态寄存器TFSR_EL1。如果是这样,内核能够为自己清除标记检查失败标志,这将是一个弱点,很可能构成最简单的未知标记绕过利用的一部分。这个弱点在用户空间不存在,因为需要切换到内核模式才能清除标记检查失败位,而切换到内核模式的过程应该能检测到异步标记检查失败并适当地分发错误。
  4. DMA - 通常,系统上的多个设备对物理内存的各个区域具有DMA访问权限,对于GPU或硬件加速器等复杂设备,这包括动态映射普通用户空间或内核空间内存的部分区域。这可能带来多个问题——任何设置设备映射的代码对安全性已经至关重要,但这也有可能被攻击者用来构建强大的原语(在"首次无效访问"之后)。
  5. 来自系统上未启用MTE核心的DMA - 我们已经看到现实中的攻击者开始使用协处理器漏洞来绕过内核缓解措施,如果这些协处理器采用的通用软件缓解措施水平较低,我们可以预计这种情况会持续下去。这本身并不是不在内核中使用MTE的理由——只是我们应该牢记这一点,特别是在考虑将更多代码转移到协处理器所带来的安全影响时。

此外,还存在一些限制覆盖范围的问题(由于Linux内核当前的实现细节):

  1. kcmp系统调用对于内核指针的保密性是有问题的,因为它允许用户空间比较两个struct file*指针是否相等。其他系统调用也有类似的实现细节,允许用户空间泄露关于内核指针相等性的信息(例如fuse_lock_owner_id)。

  2. 与上述问题类似,一些内核数据结构使用指针作为键,这也曾被用来向用户空间泄露内核指针信息。(参见此处,搜索epoll_fdinfo)。这对于用户空间使用MTE也是一个问题,特别是在例如浏览器渲染器进程的上下文中,但这里要强调的是,Linux内核中已知存在这种模式的实例,并且已经被公开利用过。

  3. TYPESAFE_BY_RCU区域按设计需要/允许释放后使用访问,因此这些区域中的分配目前无法通过内存标记进行保护。(参见此讨论串了解一些讨论)。

  4. 除了跳过特定的标记检查失败(如上面列表中的第3点),攻击者目前也可能通过单次内存写入来禁用kasan。这也将是一个需要避免的单点故障。

[1] 一种不提供确定性保护,但攻击者可以通过"赢得"概率条件来普遍绕过的硬缓解措施。对于MTE(假设有4个标记位可用,且可能有一个值被保留),这可能意味着1/15的成功机会。