【问题标题】:Branch prediction & speculative fetch mitigation分支预测和推测性提取缓解
【发布时间】:2019-04-23 12:14:11
【问题描述】:

为什么虚拟地址 (VA) 分离不足以缓解各种幽灵和崩溃缺陷?我的意思是通用的,不包括攻击intel p-cache == v-cache hack的那个;这显然是个坏主意,我找不到任何同情。

作为基线:

  1. 我的内核地址空间 (AS) 只与用户 AS 共享一个文本和数据页。这些页面包含足够的代码和数据来保存和存储寄存器;加载一个新的内存上下文,然后跳转到合适的地方。因此,这里没有有趣的地址可供发现。

  2. 来自 exec 的进程 AS 没有任何共同的 VA。也就是说,每个 VA 分配都是从一个公共池中获取的,因此即使是像 libc 这样的共享对象在每个进程中都位于不同的地址。大多数 unix 派生的人会觉得这很奇怪,但这当然是可行的;我错误地做了一次^H*10/为了测试。

  3. 如果 Fork() 处理的图像位于不同的访问控制域中,则它们将被沙箱化,以防止交叉泄漏。沙盒可能涉及上下文切换缓存驱逐、排除超线程的 cpuset,一直到无干扰内核。

我了解 [1] 是解决崩溃相关问题的基本缓解措施; [2] 是 [1] 的扩展,因此适用于幽灵。 [3] 会导致性能问题,但同样仅限于这些情况。

【问题讨论】:

  • 你在说什么攻击intel p-cache == v-cache hack?我完全理解 Spectre 和 Meltdown 是什么以及它们是如何工作的,但这听起来不像它们中的任何一个。听起来您在谈论 VIPT L1d 缓存,它通过具有足够的关联性使索引位全部来自页面内的偏移量来避免混叠问题(因此可以免费转换,因此缓存的行为类似于 PIPT 但仍然可以做TLB 翻译与从索引集中获取数据+标签并行)。这不是崩溃的原因。

标签: x86 arm x86-64 cpu-architecture branch-prediction


【解决方案1】:

Meltdown 攻击依赖于(推测性地)直接(从攻击过程中)访问目标虚拟地址1

但幽灵不是。 您启动 分支预测器,以便受到攻击的代码推测性地访问它自己的虚拟地址空间,这是它有权执行的操作。 分支预测器别名意味着您通常/有时可以在您无法/没有映射的虚拟地址处为分支进行预测。 (例如在内核中。)

通常的侧通道,即缓存读取攻击,是基于逐出您自己地址空间中的数组的缓存。但是其他侧通道可以将 Spectre 数据从目标返回给攻击者,例如启动缓存,然后查找哪个条目因冲突未命中而被逐出,以获取 aliases 一些地址进程中的内存受到攻击。 (更难,因为现代 x86 CPU 中的 L3 缓存使用复杂的索引功能,这与使用简单的位范围作为索引的更简单的缓存不同。但可能您可以使用 L2 或 L1d 未命中。 L2 未命中/L3 命中仍应明显长于 L2 命中。)

或者使用 SMT(例如超线程),一种 ALU 计时攻击,其中 Spectre 小工具会创建与数据相关的 ALU 端口压力。在这种情况下,唯一相关的内存访问是受到攻击的数据(硬件允许,只有错误推测分支会导致回滚,而不是加载错误)。


攻击内核时,会将攻击进程的物理内存页映射到某处。 (大多数内核将所有物理内存映射到连续的虚拟地址范围,从而可以轻松访问任何物理地址。)缓存基于物理地址,而不是虚拟地址。

通过同一页面的不同映射使高速缓存行变热的 Spectre 小工具仍然有效。

在系统调用的上下文中,内核通常将用户空间内存映射到它在进程内使用的相同虚拟地址,因此像readwrite这样的系统调用可以在用户空间和页面缓存之间复制。许多系统调用将用户空间指针传递给文件名。因此,在攻击内核时,Spectre gadget 可以直接在攻击过程中使用用户空间地址。

Spectre 小工具本身甚至可能位于用户空间内存中,尽管使用单独的页表来解决 Meltdown,您可以通过将内核页表设置为在没有 exec 权限的情况下映射用户空间 VA 来缓解这种情况。


脚注 1:Meltdown 是绕过页表中的 U/S 位,允许用户空间潜在地读取内核留下映射的任何内存。是的,[1] 是一个足够的解决方法。见http://blog.stuffedcow.net/2018/05/meltdown-microarchitecture/

【讨论】:

  • 现代内核,至少是我研究过的内核,不会映射所有的物理内存;那是1970年代的事情。现代内核甚至没有办法这样做。分支预测器使用散列?我只在一个架构中真正看到过,当然没有;所以要训练分支预测器,你必须用精确的 VA 来训练它。同意的 SMT 主要是垃圾,但我想这在 15 年前就已经知道了。
  • @mevets:x86-64 上的 Linux 直接映射所有物理内存,最高可达 64TB。注意kernel.org/doc/Documentation/x86/x86_64/mm.txt 中的direct mapping of all physical memory (page_offset_base) 条目。对于 56 位 5 级页表,直接映射大小高达 32 PB。
  • 谢谢,顺便说一句;我认为这是内核人员和 cpu 人员之间的懒惰结合;但是 BP 的混乱确实让整个火车都被 cpu 人踩在脚下。
  • Linux 不是现代操作系统,而是任何人的想象力。
  • @mevets:TAGE 分支预测器的名称中确实有“标记”,但我的理解是它们基本上允许别名。最常见的分支支配了对分支历史和地址组合的预测,并且没有一个罕见的别名分支消除了有价值的状态。 Paul Clayton 认为 TAGE 可以/确实使用 partial 标记:Why did Intel change the static branch prediction mechanism over these years?。另见 Bee 的 cmets here
猜你喜欢
  • 2016-09-14
  • 2015-11-24
  • 2020-12-16
  • 2014-04-25
  • 2014-03-03
  • 2014-07-03
  • 2019-08-19
  • 2016-07-01
  • 2011-02-01
相关资源
最近更新 更多