From d103ea92da66722264f3cf0b148c4118ce47d8dc Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Tue, 14 May 2019 22:27:06 +0800 Subject: upd --- chap/chap2.tex | 15 ++-- chap/chap3.tex | 271 ++++++++++++++++++++++++++++++++++++++------------------- chap/chap4.tex | 5 +- thesis.bib | 31 +++++++ 4 files changed, 223 insertions(+), 99 deletions(-) diff --git a/chap/chap2.tex b/chap/chap2.tex index 3bd6a65..5c8e73a 100644 --- a/chap/chap2.tex +++ b/chap/chap2.tex @@ -680,10 +680,13 @@ Spectre v2 利用间接转移的推测式执行,用于预测间接转移的主 尽管上面的示例假设攻击者控制两个寄存器,但攻击者控制单个寄存器,堆栈上 的值或内存值对于某些小工具来说已足够。 -在许多方面,利用类似于面向返回的编程(ROP),除了正确编写的软件易受攻 -击,小工具的持续时间有限但不需要干净地终止(因为CPU最终会识别推测错误) -和小工具必须通过旁道而不是明确地渗透数据。仍然,推测执行可以执行复杂的 -指令序列,包括从堆栈读取,执行算术,分支(包括多次)和读取存储器。 +从很多方面,这种攻击类似于面向返回编程 +(ROP)\supercite{ret2libc}。在ROP 中,攻击者从受害程序所用的 C 库等代 +码中寻找大量的指令序列,合并到一起形成一个组件,攻击者可以构造出能进行 +任意计算的组件。而在 Spectre v2 攻击中,受攻击的程序是正确编写的软件, +构造出的组件是暂态执行的,指令数目有限,然而攻击者仍然可以让处理器推测 +式执行复杂的指令序列,利用侧信道泄露数据。 + 在x86处理器上模糊分支预测器。 @@ -747,9 +750,9 @@ Prime+Probe 方式进行 Meltdown 和 Spectre 攻击的形式。通过利用缓 %%%%%%%%%%%%%%%%%% gtran %%%%%%%%%%%%%%%%%%%%%%%%%%% -\verb|TODO|: NetSpectre 的 introduction +%\verb|TODO|: NetSpectre 的 introduction -\Fixme: 重新翻译此内容 +%\Fixme: 重新翻译此内容 NetSpectre\supercite{netspectre} 是通过网络进行的 Spectre 攻击,使得 Spectre 攻击可以用于不运行攻击者控制的代码的系统上,从而更多的设备受到 diff --git a/chap/chap3.tex b/chap/chap3.tex index ffbdbe1..aaa7956 100644 --- a/chap/chap3.tex +++ b/chap/chap3.tex @@ -1,12 +1,7 @@ -% Copyright (c) 2014,2016,2018 Casper Ti. Vector -% Public domain. - -\chapter{Meltdown和Spectre攻击的防御方案分析}\label{sec:defense} +\chapter{Meltdown 和 Spectre 攻击的防御方案及分析}\label{sec:defense} Meltdown 和 Spectre 及其多种变体被发现后,研究者提出了多种减轻这些攻击 -的防御方法,它们需要对软件或硬件进行修改。也有研究者提出通过修改现有的 -指令系统\supercite{oisa},使得用这种指令系统的程序不受 Spectre 攻击的 -影响。 +的防御方法,它们需要对软件或硬件进行修改。 \section{Meltdown型攻击的防御} @@ -197,9 +192,39 @@ SafeSpec\supercite{safespec}提出了一种原则性的方法来保护处理器 InvisiSpec \supercite{invisispec} 使推测式执行产生的副作用在数据缓存中 不可见,从而可以防御利用推测式执行的攻击。它的目标是阻止由推测式执行的 装载操作产生的微架构侧信道和隐蔽信道,如缓存占用、缓存行替换算法信息、 -缓存一致性状态等。它不但要防御基于分支推测式执行的 Spectre 攻击,而且 -还要防御未来可能利用到推测式执行中的装载操作的攻击。和 SafeSpec 不同, -InvisiSpec 支持多处理器。 +缓存一致性状态等。和 SafeSpec 不同,InvisiSpec 支持多处理器。 + +Spectre 等攻击由暂态指令引起,为了定义 InvisiSpec 的攻击模型, +表\ref{tab:transient_insn}列出了各种攻击中暂态指令的来源。InvisiSpec 关 +注基于缓存的侧信道和隐蔽信道,因此只考虑装载指令。InvisiSpec 不但要防 +御 Spectre 攻击,并且还要防御未来的攻击。未来的攻击中有多种暂态指令的来 +源。根据这两类攻击,InvisiSpec 设计了两种模型模 +型:Spectre 和 Futuristic. + +\begin{table} +\begin{tabular}{|c|c|} +\hline +攻击 & 暂态指令的来源\tabularnewline +\hline +\hline +Meltdown & \multirow{2}{*}{虚拟内存异常}\tabularnewline +\cline{1-1} +L1TF & \tabularnewline +\hline +LazyFP & \multirow{2}{*}{读取禁用的或者特权寄存器发生异常}\tabularnewline +\cline{1-1} +Rogue System Register Read & \tabularnewline +\hline +Spectre & 控制流预测错误\tabularnewline +\hline +Speculative Store Bypass & 装载指令和更早的存储指令地址别名\tabularnewline +\hline +未来的攻击 & 异常、控制流预测错误、访存别名、一致性违例、中断等\tabularnewline +\hline +\end{tabular} +\caption{暂态指令的来源} +\label{tab:transient_insn} +\end{table} InvisiSpec 的微架构基于两种机制。第一个机制中,不安全的推测式执行的装载 操作将数据读入至推测式执行缓冲区(Speculative Buffer,SB)中,而不读入 @@ -227,36 +252,30 @@ TSO(Total Store Order)是 x86 体系结构所用的内存模型。TSO 允许 RC(Release Consistency)则允许任何访存操作的重排序,除非使用同步指令。 -\begin{tabular}{|c|c|} -\hline -攻击 & 暂态指令的来源\tabularnewline -\hline -\hline -Meltdown & \multirow{2}{*}{虚拟内存异常}\tabularnewline -\cline{1-1} -L1TF & \tabularnewline -\hline -LazyFP & \multirow{2}{*}{读取禁用的或者特权寄存器发生异常}\tabularnewline -\cline{1-1} -Rogue System Register Read & \tabularnewline -\hline -Spectre & 控制流预测错误\tabularnewline -\hline -Speculative Store Bypass & 装载指令和更早的存储指令地址别名\tabularnewline -\hline -未来的攻击 & 异常、控制流预测错误、访存别名、一致性违例、中断等\tabularnewline -\hline -\end{tabular} - InvisiSpec 关注不安全的推测式执行的装载指令(Unsafe Speculative Load,USL),在 Spectre 的攻击模型中,USL 是在未决分支之后的装载指令, 在得到分支结果后,正确路径上的 USL 转为安全的装载指令。而在未来攻击的模 型中,USL 变为安全仅当指令到达 ROB 头部,或不被可能中断该指令的事件回 卷。 -\Todo: InvisiSpec V: INVISISPEC: THWARTING SPECULATION ATTACKS +InvisiSpec 的目的是使 USL 在缓存层次结构中不可见,这意味着 USL 不可以用 +其他线程可见的方式修改缓存层次结构,包括一致性状态。到了一个时间 +点,USL 可以转为安全的装载操作,这个时间称为可见时间点(Visibility +Point),这时其他线程可以看到这个操作在存储系统中的效果。InvisiSpec 通 +过重新装载数据,将数据存入本地缓存,改变缓存层次结构的状态。 + +在 USL 发射至可见的时间段里,它不改变任何缓存一致性状态,处理器核可能无 +法接收对 USL 对应的缓存行的失效请求,从而检测不到这个装载指令对内存一致 +性模型的违例。为了解决这个问题,InvisiSpec 需要进行一个验证的步骤,它在 +可见时间点重新装载数据。 + +USL 请求的缓存行在 USL 发射时有可能已经在一级缓存中,这个缓存行也被载 +入推测式执行缓冲区。处理器可能接收对这一行的失效请求,但是 USL 会忽视 +这个请求,这个失效请求的效果的会在可见时间点处理。 -\Fixme: 重新翻译以下内容 +%\Todo: InvisiSpec V: INVISISPEC: THWARTING SPECULATION ATTACKS + +%\Fixme: 重新翻译以下内容 %1)不安全的推测负载:严格地说,任何在到达ROB头部之前启动读取的负载都是推测负载。在这项工作中,我们对可能由于推测而产生安全漏洞的(大)投机负载子集感兴趣。我们称这些负载为Unsafe Speculative Loads(USLs)。作为USL的一组推测性负载取决于攻击模型。 @@ -266,66 +285,105 @@ Load,USL),在 Spectre 的攻击模型中,USL 是在未决分支之后的 %要了解为什么这两个条件允许USL过渡到安全负载,请考虑以下内容。 ROB头上的负载本身不能是瞬态的;它可以被压扁(例如,由于异常),但它是一个正确的指令。关于推测性非可压缩负载也可以这样说。这是因为,虽然不在ROB头部,但是它们不能被任何先前的指令压扁,因此可以被认为是ROB头部处的指令的逻辑扩展。 -2)使USLs看不见:InvisiSpec背后的想法是让USL隐形。这意味着USL无法以任何其他线程可见的方式修改缓存层次结构,包括一致性状态。 USL将数据加载到我们称为Speculative Buffer(SB)的特殊缓冲区中,而不是加载到本地缓存中。如上所述,USL可以转换到安全负载的时间点。此时,称为可见性点,InvisiSpec采取的行动将使USL可见 - 即,将使USL在内存层次结构中的所有副作用对所有其他线程都明显。 InvisiSpec通过重新加载数据使USL可见,这次将数据存储在本地缓存中并更改缓存层次结构状态。负载可能仍然是推测性的。 +%2)使USLs看不见:InvisiSpec背后的想法是让USL隐形。这意味着USL无法以任何其他线程可见的方式修改缓存层次结构,包括一致性状态。 USL将数据加载到我们称为Speculative Buffer(SB)的特殊缓冲区中,而不是加载到本地缓存中。如上所述,USL可以转换到安全负载的时间点。此时,称为可见性点,InvisiSpec采取的行动将使USL可见 - 即,将使USL在内存层次结构中的所有副作用对所有其他线程都明显。 InvisiSpec通过重新加载数据使USL可见,这次将数据存储在本地缓存中并更改缓存层次结构状态。负载可能仍然是推测性的。 + +%3)维护内存一致性:负载的可抑制可见性窗口是从USL发出负载到使其自身可见之间的时间段。在此期间,由于USL不会更改任何一致性状态,因此核心可能无法接收针对USL加载的线路的无效。因此,负载违反内存一致性模型存在未检测到的风险。这是因为这种违规通常是通过传入的失效来检测的,并且通过压缩负载来解决。要解决此问题,InvisiSpec可能必须在负载的可见点重新加载数据时执行验证步骤。 -3)维护内存一致性:负载的可抑制可见性窗口是从USL发出负载到使其自身可见之间的时间段。在此期间,由于USL不会更改任何一致性状态,因此核心可能无法接收针对USL加载的线路的无效。因此,负载违反内存一致性模型存在未检测到的风险。这是因为这种违规通常是通过传入的失效来检测的,并且通过压缩负载来解决。要解决此问题,InvisiSpec可能必须在负载的可见点重新加载数据时执行验证步骤。 +%当USL发布并且线路加载到SB时,USL请求的线路可能已经在核心的L1缓存中。在这种情况下,核心可能会收到该行的无效。但是,USL忽略了这种失效,因为USL是不可见的,并且这种失效的任何影响都将在可见点处理。 -当USL发布并且线路加载到SB时,USL请求的线路可能已经在核心的L1缓存中。在这种情况下,核心可能会收到该行的无效。但是,USL忽略了这种失效,因为USL是不可见的,并且这种失效的任何影响都将在可见点处理。 +在可见时间点重新装载数据,有两种操作形式:验证(Validation)和曝光 +(Exposure)。验证操作将 USL 用到的数据,和存储系统中这些数据的最新的值 +做比较,如果不相同,USL 和其后的所有指令都需要重新执行。这个操作用于满 +足内存一致性模型,方法类似于基于值的内存保序方法。\supercite{cain-lapasti} -4)USL的验证或曝光:在可见性点重新加载数据的操作有两种形式:验证和曝光。如果在该窗口期间,核心已经收到USL加载的行的无效,则验证是在可抑制可见性窗口期间(由于内存一致性考虑)使可见的USL可见的方法。验证操作包括将USL使用的实际字节(存储在SB中)与从缓存层次结构加载的最新值进行比较。如果它们不相同,USL及其所有连续指令都会被压扁。这是满足内存一致性模型所必需的。这一步让人想起Cain和Lipasti的基于价值的记忆排序[31]。 +%如果在该窗口期间,核心已经收到USL加载的行的无效,则验证是在可抑制可见性窗口期间(由于内存一致性考虑)使可见的USL可见的方法。验证操作包括将USL使用的实际字节(存储在SB中)与从缓存层次结构加载的最新值进行比较。如果它们不相同,USL及其所有连续指令都会被压扁。这是满足内存一致性模型所必需的。这一步让人想起Cain和Lipasti的基于价值的记忆排序[31]。 - 验证可能很昂贵。持久验证的USL在事务结束之前不能退出 - 即,从高速缓存层次结构获得的行被加载到高速缓存中,行的数据与SB中使用的子集进行比较,并做出关于压缩的决定。因此,如果USL位于ROB头并且ROB已满,则管道停止。 +USL 在验证阶段不能提交,需要等待验证结束,在这个时间段需要从存储系统获 +取缓存行并写入缓存,比较推测式执行缓冲区和读入的缓存行中,USL 所要使用 +的数据。如果 USL 在 ROB 队头并且 ROB 已满,会导致流水线停顿。 -值得庆幸的是,InvisiSpec识别出许多在其抑制可见性窗口期间无法违反内存一致性模型的USL,并允许它们以廉价的曝光可见。 如果在该窗口期间核心已经收到USL加载的行的无效,则这些USL在禁用可见性窗口期间不会被内存一致性模型压扁。 在曝光中,缓存层次结构返回的行只是存储在缓存中而不进行比较。 一旦将行请求发送到缓存层次结构,持续曝光的USL就会退出。 因此,USL不会阻止管道。 +InvisiSpec 可以识别很多在 USL 可见之前,不会违反内存一致性模型的 USL, +并对它们使用开销较低的曝光操作。这个操作只需要将读取到的一行数据存入缓 +存,当请求发送至存储系统后,指令即可提交,从而不会使流水线停顿。 -总而言之,有两种方法可以使USL可见:验证和曝光。 内存一致性模型确定需要哪一个。 图2显示了具有验证和曝光的USL的时间线。 +%值得庆幸的是,InvisiSpec识别出许多在其抑制可见性窗口期间无法违反内存一致性模型的USL,并允许它们以廉价的曝光可见。 如果在该窗口期间核心已经收到USL加载的行的无效,则这些USL在禁用可见性窗口期间不会被内存一致性模型压扁。 在曝光中,缓存层次结构返回的行只是存储在缓存中而不进行比较。 一旦将行请求发送到缓存层次结构,持续曝光的USL就会退出。 因此,USL不会阻止管道。 -InvisiSpec的负载有两个步骤。首先,当它作为USL发布到内存时,它访问缓存层次结构并获得所请求的缓存行的当前版本。该行仅存储在本地SB中,本地SB与L1高速缓存一样靠近核心。 USL不修改高速缓存一致性状态,高速缓存替换算法状态或任何其他高速缓存层次结构状态。没有其他线程(本地或远程)可以看到任何更改。但是,核心使用USL返回的数据来取得进展。 SB存储行而不是单个词来利用空间局部性。 +%总而言之,有两种方法可以使USL可见:验证和曝光。 内存一致性模型确定需要哪一个。 图2显示了具有验证和曝光的USL的时间线。 -当可以使USL可见时,并且总是在它收到其请求的高速缓存行之后,硬件触发验证或暴露事务。这样的事务再次重新请求该行,这次修改缓存层次结构,并将该行带到本地缓存。如第V-A4部分所述,验证和暴露交易的运作方式不同,并且具有不同的性能影响。 +%InvisiSpec的负载有两个步骤。首先,当它作为USL发布到内存时,它访问缓存层次结构并获得所请求的缓存行的当前版本。该行仅存储在本地SB中,本地SB与L1高速缓存一样靠近核心。 USL不修改高速缓存一致性状态,高速缓存替换算法状态或任何其他高速缓存层次结构状态。没有其他线程(本地或远程)可以看到任何更改。但是,核心使用USL返回的数据来取得进展。 SB存储行而不是单个词来利用空间局部性。 -我们考虑两种攻击模型,幽灵和未来派,并提出略微不同的InvisiSpec设计来抵御这些攻击中的每一种。在我们对Specter攻击的防御中,USL在其所有先前的控制流指令解决时达到其可见性点。此时,硬件根据内存一致性模型和负载在ROB中的位置(第V-C节)发出负载的验证或暴露事务。如果多个USL可以发出验证或暴露交易,则交易必须按程序顺序开始,否则全部重叠(第V-D节)。 +%当可以使USL可见时,并且总是在它收到其请求的高速缓存行之后,硬件触发验证或暴露事务。这样的事务再次重新请求该行,这次修改缓存层次结构,并将该行带到本地缓存。如第V-A4部分所述,验证和暴露交易的运作方式不同,并且具有不同的性能影响。 -在我们对未来攻击的防御中,USL只有在以下情况下才能达到其可见性:( i)它不再是推测因为它位于ROB的头部,或者(ii)它仍然是推测性的,但不能再被压扁。此时,硬件根据内存一致性模型和负载在ROB中的位置(第V-C节)发出负载的验证或暴露。如果多个USL可以发出验证或暴露交易,则必须按程序顺序发布交易。但是,当发布验证交易时,后续验证或暴露交易不会与之重叠;在验证完成之前,他们都必须等待发布(第V-D节)。另一方面,当发出暴露交易时,直到并包括下一个验证交易的所有后续暴露交易都可以与之重叠(第V-D节)。 +InvisiSpec 针对 Spectre 和 Futuristic 两种攻击模型的设计略有不同。对 +于 Spectre 攻击模型,USL 在此前所有的控制流指令得出结果后,则进入可见时 +间点,此时处理器可以为这个指令执行验证或曝光操作。同时这些验证和曝光操 +作在时间上可以重叠。 -总的来说,在幽灵和未来派防御设计中,当验证事务阻止ROB头部的负载退出并且ROB已满时,可能会发生唯一的管道停顿。这在未来派中比在幽灵中更有可能。 +而对于 Futuristic 模型,USL 在两种情况下可以进入可见时间点:它到达 +了 ROB 的队头,或者它不再可能被取消。当处理器执行验证操作时,其他验证或 +曝光操作不可以与之重叠,因为验证和曝光操作会改变缓存的状态,而正在验证 +的指令如果验证失败,会导致后续的指令被取消,重叠的验证或曝光操作可能泄 +露数据至缓存状态。而对于曝光操作,直至下一个验证操作之前的所有曝光操作 +均可以重叠执行。 -我们将这些设计称为InvisiSpec-Spectre(或IS-Spectre)和InvisiSpec-Future(或IS-Future)。它们显示在表II的第一行中。为了进行比较,第二行显示了如何使用基于栅栏的方法防御这些相同的攻击 - 遵循当前提出的防御幽灵的建议[32]。我们将这些设计称为Fence-Spectre和Fence- Future。前者在每个间接或有条件的分支后放置围栏;后者在每次装载前放置围栏。 +总的来说,当验证操作阻止 ROB 队头的指令提交,并且 ROB 已满时,流水线的 +停顿才可能发生。这种情况更可能发生在 Futuristic 模型中。 -与基于栅栏的设计相比,InvisiSpec提高了性能。具体而言,负载是在传统的不安全机器中推测性地执行的。一个问题是ROB头部的负载的验证事务可能使管道停滞。但是,我们将展示如何以验证次数为代价最大化曝光次数(不会导致失速)。最后,InvisiSpec确实会创建更多缓存层次结构流量并争用各种缓存端口。应该设计硬件来处理它们。 +%我们将这些设计称为InvisiSpec-Spectre(或IS-Spectre)和InvisiSpec-Future(或IS-Future)。它们显示在表II的第一行中。为了进行比较,第二行显示了如何使用基于栅栏的方法防御这些相同的攻击 - 遵循当前提出的防御幽灵的建议[32]。我们将这些设计称为Fence-Spectre和Fence- Future。前者在每个间接或有条件的分支后放置围栏;后者在每次装载前放置围栏。 -内存一致性模型确定何时使用验证以及何时使用曝光。首先考虑TSO。在高性能TSO实现中,当ROB中没有较旧的负载(或栅栏)时读取的推测性负载将不会被随后的对其读取的线路的无效进行压缩。因此,这样的USL可以在其变得可见时使用曝光。另一方面,当ROB中存在至少一个较旧的负载(或栅栏)时读取的推测性负载将被其读取的行的无效压缩。因此,这样的USL需要使用验证。 +和基于 fence 的方法相比,InvisiSpec 性能更优,因为和传统的不安全的机器 +相比,装载指令执行的时间不变。通过将更多的验证操作转化为曝光操作,可以 +减少流水线的停顿。最后一个问题是,InvisiSpec 会在存储系统中产生更大的 +流量和缓存端口的竞争。 -现在考虑RC。在这种情况下,只有在ROB中存在至少一个早期栅栏时读取的推测性负载将被线路读取的无效压缩。因此,只有那些将被要求使用验证;绝大多数负载都可以使用暴露。 +对于 TSO 内存模型,如果一个装载指令之前不存在更老的装载指令或者 fence, +则它不会被对它读取的行的失效请求取消,因此,这些 USL 在可见时间点可以使 +用曝光操作。相反,如果一个 USL 之前有其他的装载指令,则需要执行验证操 +作。而对于 RC 模型,只有在 USL 之前有 fence 的情况下,才需要执行验证操 +作。 +% TODO!!! -从这个讨论中,我们看到在TSO下观察停止管道验证的机会最高的设计是IS-Future。为了减少这些事件的发生,InvisiSpec实现了两种机制。第一个允许一些使用验证的USL代替使用曝光。第二个标识可以使用验证的USL,如果验证失败的可能性很大,则提前将它们压扁。我们接下来考虑这些机制。 +%从这个讨论中,我们看到在TSO下观察停止管道验证的机会最高的设计是IS-Future。为了减少这些事件的发生,InvisiSpec实现了两种机制。第一个允许一些使用验证的USL代替使用曝光。第二个标识可以使用验证的USL,如果验证失败的可能性很大,则提前将它们压扁。我们接下来考虑这些机制。 -1)将验证USL转换为曝光USL:假设在TSO下,USL1在ROB中存在较早的负载时启动读取。通常,InvisiSpec会将USL1标记为需要验证。但是,假设在读取时,早于USL1的ROB中的所有负载已经获得了他们请求的数据 - 特别是,如果它们是USL,则他们请求的数据已经到达SB并且已经到达传递到登记册。在这种情况下,USL1不会相对于任何早期的负载重新排序。因此,TSO不会要求在收到对其加载的线路无效时压缩USL1。因此,USL1被标记为需要曝光,而不是验证。 +%1)将验证USL转换为曝光USL:假设在TSO下,USL1在ROB中存在较早的负载时启动读取。通常,InvisiSpec会将USL1标记为需要验证。但是,假设在读取时,早于USL1的ROB中的所有负载已经获得了他们请求的数据 - 特别是,如果它们是USL,则他们请求的数据已经到达SB并且已经到达传递到登记册。在这种情况下,USL1不会相对于任何早期的负载重新排序。因此,TSO不会要求在收到对其加载的线路无效时压缩USL1。因此,USL1被标记为需要曝光,而不是验证。 -为了支持这种机制,我们用一个名为Performed的位来标记每个USL。当USL请求的数据已在SB中接收并传递到目标寄存器时设置。 +%为了支持这种机制,我们用一个名为Performed的位来标记每个USL。当USL请求的数据已在SB中接收并传递到目标寄存器时设置。 -2)USL的早期压缩需要验证:假设核心接收到其缓存中的行的失效,该行也恰好被标记为需要验证的USL加载到其SB中。接收失效表示该行已更新。此类更新通常会导致USL在可见性失败时的验证。如果此失效是由错误共享引起的,或者如果对该行的所有更新的净效果直到验证结果是无声的(即,它们将数据恢复到其初始值),则验证才能成功。由于这些条件不太可能发生,InvisiSpec会因接收失效而挤压这样的USL。还有第二个USL的案例,验证失败的可能性很高。假设USL1需要验证并且在SB中有数据。此外,有一个较早的USL2到同一行(但对于该行的不同单词),其在SB中也有其数据并需要验证。当USL2执行验证并将线路连接到核心时,InvisiSpec还会将该线路与SB中的USL1数据进行比较。如果数据不同,则表明USL1已读取陈旧数据。那时,InvisiSpec保守地压制了USL1。 +%2)USL的早期压缩需要验证:假设核心接收到其缓存中的行的失效,该行也恰好被标记为需要验证的USL加载到其SB中。接收失效表示该行已更新。此类更新通常会导致USL在可见性失败时的验证。如果此失效是由错误共享引起的,或者如果对该行的所有更新的净效果直到验证结果是无声的(即,它们将数据恢复到其初始值),则验证才能成功。由于这些条件不太可能发生,InvisiSpec会因接收失效而挤压这样的USL。还有第二个USL的案例,验证失败的可能性很高。假设USL1需要验证并且在SB中有数据。此外,有一个较早的USL2到同一行(但对于该行的不同单词),其在SB中也有其数据并需要验证。当USL2执行验证并将线路连接到核心时,InvisiSpec还会将该线路与SB中的USL1数据进行比较。如果数据不同,则表明USL1已读取陈旧数据。那时,InvisiSpec保守地压制了USL1。 % skips subsection D, E -USL执行两个事务 - 一个是首次发布时,一个是验证或公开时。现在,假设USL的第一次访问错过最后一级缓存(LLC)并访问主内存。然后,USL的第二次访问可能也是对主内存的长延迟访问。 +一个 USL 执行两个内存访问,一个在首次发射的时候,另一个在验证或曝光的 +时候。如果第一个访问在末级缓存缺失并访问主存,则第二个访问也很可能访问 +主存。 -为了提高性能,我们设计了InvisiSpec,以避免在大多数情况下进行第二次主存访问。具体来说,我们在LLC旁边添加了每核LLC推特缓冲区(LLC-SB)。当USL的第一次访问从主存储器读取该行时,当该行被发送回请求核心的L1 SB时,InvisiSpec将其副本存储在核心的LLC-SB中。之后,当USL发布其验证或曝光时,它将从核心的LLC-SB读取该行,跳过对主存储器的访问。 +为了提高性能,InvisiSpec 为每个核添加一个末级缓存推测式执行缓冲区 +(LLC-SB),USL 的第一个访问如果来自主存,则将获取的一行同时放入LLC-SB, +此后在验证时,就可以从 LLC-SB 获取数据,而无需访问主存。而在另一个核访 +问了这一行时,为了防止 LLC-SB 获取过时的数据,才需要使 LLC-SB 中的这一 +行失效,验证和曝光操作将会从存储系统中存有最新数据的地方获取数据。 -如果在两次访问之间,第二个核心通过验证/暴露或安全访问访问该线路,则InvisiSpec使来自第一个核心的LLC-SB的线路无效。这保守地确保LLC-SB不保存陈旧数据。在这种情况下,原始USL的验证或公开事务将从缓存层次结构中的任何位置获取该行的最新副本。 -%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%% 在 gem5 模拟器下, 使用 SPEC CPU2006 和 PARSEC 对 InvisiSpec 进行评测, 以 Spectre 为威胁模型,在 TSO 内存模型下,InvisiSpec 平均性能损失为 21\%,而使用 fence 性能下降 74\%. +InvisiSpec 的性能开销来源于三个方面,一个是验证导致的流水线停顿,在大 +多数程序中,这部分开销可以忽略;第二个是取消了错误执行路径后,它装载的 +数据无法被后续的指令复用;第三个是每个 USL 需要两次存储访问,造成资源 +的竞争。 + +InvisiSpec 会增大存储系统中各个缓存之间,和缓存和主存之间的网络流量, +在 TSO 下,以 Spectre 为威胁模型,相对于原处理器,流量增大 34\%. + \subsubsection{DAWG} \Todo: DAWG introduction \Fixme: 重新翻译 -在一个设计良好的系统中,攻击者无法在架构上观察到这个秘密,因为秘密应该 +在一个设计良好的系统中,无法在架构上观察到这个秘密,因为秘密应该 局限于一个保护域,阻止其他程序在架构上观察它。但是,当攻击者可以通过软 件方式观察执行的副作用时,可能存在漏洞。 @@ -411,46 +469,39 @@ DAWG 的主要缺点是需要操作系统的支持。此外,DAWG 不能防御 \subsubsection{Context-Sensitive Fencing} -\Todo: CSF introduction - -\Fixme: 重新翻译 +%\Todo: CSF introduction -这项工作提出了上下文敏感的防护,一种针对幽灵的新型微码级防御。防御策略 -的关键组成部分包括:(a)微码定制机制,允许处理器手动将栅栏插入动态指 -令流,以减轻推测性执行的不良副作用,(b)解码器级信息流跟踪(DLIFT) -)框架,用于识别可能不安全的执行模式以触发微代码定制,以及(c)缓解保 -护分支预测器和返回地址堆栈的缓解措施。 +%\Fixme: 重新翻译 -为了在对性能影响最小的情况下执行安全的微码定制,这项工作利用了上下文敏 -感解码(CSD)[68],这是最近提出的对英特尔(和其他人)微操作转换机制的 -扩展,可实现按需和上下文敏感自定义动态微操作指令流。此外,这项工作还利 -用了CSD提供的重新配置框架,允许操作系统和其他可信实体动态控制通过外科 -手术插入微操作流的投机栅栏的频率,类型和行为,以确保投机安全执行。 +% 为了在对性能影响最小的情况下执行安全的微码定制,这项工作利用了上下文敏 +% 感解码(CSD)[68],这是最近提出的对英特尔(和其他人)微操作转换机制的 +% 扩展,可实现按需和上下文敏感自定义动态微操作指令流。此外,这项工作还利 +% 用了CSD提供的重新配置框架,允许操作系统和其他可信实体动态控制通过外科 +% 手术插入微操作流的投机栅栏的频率,类型和行为,以确保投机安全执行。 -这项工作分析了一套显着扩展的围栏,考虑了不同的可能的执法阶段和执法策略。 -特别是,我们引入了一个新的栅栏,可以防止推测性更新缓存状态,同时在指令 -的动态调度中具有最小的干扰。 +% 这项工作分析了一套显着扩展的围栏,考虑了不同的可能的执法阶段和执法策略。 +% 特别是,我们引入了一个新的栅栏,可以防止推测性更新缓存状态,同时在指令 +% 的动态调度中具有最小的干扰。 -上下文敏感的防护能够通过基于解码器级信息流跟踪的新型检测机制自动识别网 -格插入点。由于处理器前端通常以比管线的其余部分高得多的速率搅拌指令,因 -此解码器级的信息流跟踪易于频繁过度和不确定的情况。虽然由于栅栏插入的频 -率增加而导致过度拉伸可能会损害性能,但是对于短暂的窗口来说,不确定会破 -坏系统的安全性。通过早期低开销的错误检测和恢复机制解决这些挑战,本文进 -一步确定了解码器级信息流跟踪作为一种有效的攻击检测机制的可行性。 +% 上下文敏感的防护能够通过基于解码器级信息流跟踪的新型检测机制自动识别网 +% 格插入点。由于处理器前端通常以比管线的其余部分高得多的速率搅拌指令,因 +% 此解码器级的信息流跟踪易于频繁过度和不确定的情况。虽然由于栅栏插入的频 +% 率增加而导致过度拉伸可能会损害性能,但是对于短暂的窗口来说,不确定会破 +% 坏系统的安全性。通过早期低开销的错误检测和恢复机制解决这些挑战,本文进 +% 一步确定了解码器级信息流跟踪作为一种有效的攻击检测机制的可行性。 -这项工作进一步提出了新的微操作流程,保护分支预测器和返回地址堆栈,防止 -跨不同保护域的错误训练和/或逆向工程。虽然与英特尔提出的间接分支预测器 -屏障(IBPB)指令的精神相似,但这些微操作流程更广泛地应用于更广泛的分支 -预测器和返回地址堆栈,并提供更细粒度的控制。 +% 这项工作进一步提出了新的微操作流程,保护分支预测器和返回地址堆栈,防止 +% 跨不同保护域的错误训练和/或逆向工程。虽然与英特尔提出的间接分支预测器 +% 屏障(IBPB)指令的精神相似,但这些微操作流程更广泛地应用于更广泛的分支 +% 预测器和返回地址堆栈,并提供更细粒度的控制。 -\Todo: 更详细地介绍 CSF +% \Todo: 更详细地介绍 CSF Context-Sensitive Fencing(CSF)\supercite{context-sensitive-fencing} 是 一种微码级防御多种类型 Spectre 攻击的方法。它基于 Context-Sensitive Decoding (CSD)\supercite{context-sensitive-decoding},一种微码翻译机制 的扩展,用于动态按需自定义微操作指令流。CSF 利用 CSD,在微指令流中注入 -fence 等微码,阻止不安全指令的推测式执行。为了降低 fence 的性能开销, -CSF 还提出了3种新的用于防御 Spectre 的 fence. +fence 等微码,阻止不安全指令的推测式执行。 CSF 由以下几个关键部件组成: \begin{itemize} @@ -461,6 +512,39 @@ CSF 由以下几个关键部件组成: \item 错误训练防御:用于保护分支预测器、返回地址栈等部件 \end{itemize} +为了降低 fence 的性能开销,CSF 还提出了3种新的用于防 +御 Spectre 的 fence. 在 fence 操作的设计上有以下考虑: + +\begin{itemize} +\item 作用位置:x86 的 lfence 作用在指令队列阶段,使得后续的指令 + 在lfence 提交前无法进入指令队列后的流水线结构。fence 作用在更晚的阶段 + 的结构,可以减少 fence 对性能的影响,而保护的侧信道更少。 +\item 严格和宽松的 fence:严格的 fence 会阻止所有指令越过 fence,而宽松 + 的 fence 允许某些指令越过它们。例如 lfence 是个严格 + 的 fence,而 sfence 允许存储指令之外的指令越过 fence,是个宽松 + 的 fence. +\end{itemize} + +表 \ref{tab:csffence} 是 CSF 定义的三种 fence,它们防御的 Spectre 变体 +有所不同。 + +\begin{table} +\begin{tabular}{cccccc} +\hline +fence & 作用位置 & 严格/宽松 & 不允许的指令 & 防御的攻击种类\tabularnewline +\hline +LSQ-LFENCE & LSQ & 宽松 & 装载 & v1\tabularnewline +\hline +LSQ-MFENCE & LSQ & 宽松 & 装载和存储 & v1,v1.1,v1.2\tabularnewline +\hline +CFENCE & 缓存控制器 & 宽松 & 无 & v1\tabularnewline +\hline +\end{tabular} +\caption{CSF 新定义的三种 fence} +\label{tab:csffence} +\end{table} + + CSF 防御 Spectre 的开销在 8\% 以下。 \subsubsection{Conditional Speculation} @@ -527,10 +611,12 @@ SpectrePrime & 条件分支 & 访存\tabularnewline 当新的指令分发至发射队列时,处理器在发射队列的位置 X 处分配一个条目, 此时对发射队列中所有有效的指令 Y,计算 $Matrix[X,Y]$: -$Matrix[X,Y] = (IQ[X].opcode == Memory) \\ - \phantom{=}\& (IQ[Y].opcode == Memory || IQ[Y].opcode == Branch) \\ - \phantom{=}\& IQ[Y].valid \\ - \phantom{=}\& !IQ[Y].issued$ +\begin{align*} +Matrix[X,Y] {}={} & (IQ[X].opcode == Memory) \\ + & \&{} (IQ[Y].opcode == Memory {} || {} IQ[Y].opcode == Branch) \\ + & \&{} IQ[Y].valid \\ + & \&{} !IQ[Y].issued +\end{align*} 这个公式的含义如下:X 在进入发射队列之前 Y 有效,则意味着 Y 在 X 之前; 对于多种 Spectre 变体,只需要检查访存指令是否依赖于先前的分支或访存指 @@ -679,3 +765,6 @@ Spectre 攻击需要分为三个步骤:从存储系统装载秘密数据,将 % \end{comment} % % % vim:ts=4:sw=4 + +\section{Meltdown 和 Spectre 的防御方案分析} + diff --git a/chap/chap4.tex b/chap/chap4.tex index 5be6d75..ab8b34f 100644 --- a/chap/chap4.tex +++ b/chap/chap4.tex @@ -31,8 +31,9 @@ DIFT 可以作为 Spectre 攻击的检测手段之一。Spectre 的论文中指 法则是这种观点的一种具体设计。在其他使用了 DIFT 的防御 Spectre 的设计中, 所追踪的对象有所不同。CSF\supercite{context-sensitive-fencing} 中的译码 级信息流追踪框架 DIFT,用于追踪处理器使用的数据是否来源于用户输入,从而 -处理器可以根据此信息判断是否需要插入 fence 微码。OISA\supercite{oisa} -在指令系统的定义中即包含了 DIFT 技术,用于追踪一个数据是否为秘密数据。 +处理器可以根据此信息判断是否需要插入 fence 微码。有的指令系 +统\supercite{oisa}在定义中即包含了 DIFT 技术,用于追踪一个数据是否为秘 +密数据。 和 Conditional Speculation \supercite{conditional-speculation} 的 TPBuf 过滤器一样,本文的工作同样 diff --git a/thesis.bib b/thesis.bib index 83f3936..8087ee9 100644 --- a/thesis.bib +++ b/thesis.bib @@ -34,6 +34,24 @@ year = {2019}, } +@inproceedings{ret2libc, + author = {Shacham, Hovav}, + title = {The Geometry of Innocent Flesh on the Bone: Return-into-libc Without Function Calls (on the x86)}, + booktitle = {Proceedings of the 14th ACM Conference on Computer and Communications Security}, + series = {CCS '07}, + year = {2007}, + isbn = {978-1-59593-703-2}, + location = {Alexandria, Virginia, USA}, + pages = {552--561}, + numpages = {10}, + url = {http://doi.acm.org/10.1145/1315245.1315313}, + doi = {10.1145/1315245.1315313}, + acmid = {1315313}, + publisher = {ACM}, + address = {New York, NY, USA}, + keywords = {instruction set, return-into-libc, turing completeness}, +} + @online{msvc, author = {Paul Kocher}, title = {Spectre Mitigations in Microsoft's C/C++ Compiler}, @@ -286,6 +304,19 @@ doi={10.1109/MICRO.2018.00042}, ISSN={}, month=Oct,} +@ARTICLE{cain-lapasti, +author={H. W. {Cain} and M. H. {Lipasti}}, +journal={IEEE Micro}, +title={Memory ordering: a value-based approach}, +year={2004}, +volume={24}, +number={6}, +pages={110-117}, +keywords={content-addressable storage;data integrity;data structures;instruction sets;memory architecture;reduced instruction set computing;storage management;memory ordering;value-based replay;load instructions;first-in-first-out buffer;heuristics filter;cache storage;content addressable memory;memory consistency;Insulation;Bandwidth;Hazards;Computer aided manufacturing;CADCAM;Scalability;Costs;Filters;Degradation;Computer aided instruction}, +doi={10.1109/MM.2004.81}, +ISSN={0272-1732}, +month={Nov},} + @INPROCEEDINGS{dawg, author={V. {Kiriansky} and I. {Lebedev} and S. {Amarasinghe} and S. {Devadas} and J. {Emer}}, booktitle={2018 51st Annual IEEE/ACM International Symposium on Microarchitecture (MICRO)}, -- cgit v1.2.3