From 3f83b8392ec40b23374b3005b4f08c5b39f1c8c1 Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Tue, 28 May 2019 10:54:20 +0800 Subject: fixes DIFT --- chap/chap1.tex | 36 ++++++------ chap/chap2.tex | 3 +- chap/chap3.tex | 6 +- chap/chap4.tex | 183 ++++++++++++++++++++++++++++++--------------------------- chap/chap5.tex | 22 +++---- chap/chap6.tex | 4 +- chap/encl1.tex | 5 +- 7 files changed, 136 insertions(+), 123 deletions(-) diff --git a/chap/chap1.tex b/chap/chap1.tex index bee1ea1..5a3224d 100644 --- a/chap/chap1.tex +++ b/chap/chap1.tex @@ -92,46 +92,46 @@ Microsoft 等软件厂商,均发布了软件补丁或处理器微码更新, \section{研究平台与环境} -本文使用 gem5 模拟器\supercite{gem5}作为研究平台。 +本文使用 Gem5 模拟器\supercite{gem5}作为研究平台。 -gem5 是一个模拟平台,由 GEMS\supercite{gems} 和 M5\supercite{m5} 两个 +Gem5 是一个模拟平台,由 GEMS\supercite{gems} 和 M5\supercite{m5} 两个 模拟器项目合并而成,同时具有这两个模拟器的优点。M5 提供了一个可配置的 框架,支持多种指令系统和多种 CPU模型,GEMS 则提供了一个详细而灵活的存 -储系统,支持多种缓存一致性模型和互联模型。gem5 支持 X86, ARM, Alpha, -MIPS, RISC-V 等指令系统。作为一个开源的模拟器,学术界和工业界都为 gem5 -的开发做出贡献,使得 gem5 称为体系结构研究中最流行的模拟器之一。 +储系统,支持多种缓存一致性模型和互联模型。Gem5 支持 X86, ARM, Alpha, +MIPS, RISC-V 等指令系统。作为一个开源的模拟器,学术界和工业界都为 Gem5 +的开发做出贡献,使得 Gem5 称为体系结构研究中最流行的模拟器之一。 \begin{figure}[htbp] \centering \includegraphics[width=0.8\textwidth]{gem5_cpu.pdf} - \caption{gem5 支持的 CPU 模型\supercite{gem5-tutorial}} - \label{fig:gem5_cpu} + \caption{Gem5 支持的 CPU 模型\supercite{gem5-tutorial}} + \label{fig:Gem5_cpu} \end{figure} -gem5 的灵活性使得研究者可以根据需要选择不同的系统模型,取得模拟速度和精 -度的平衡。gem5 支持以下模型的配置: +Gem5 的灵活性使得研究者可以根据需要选择不同的系统模型,取得模拟速度和精 +度的平衡。Gem5 支持以下模型的配置: \begin{enumerate} -\item CPU 模型:如图\ref{fig:gem5_cpu},gem5 支持多种不同的 CPU 模 +\item CPU 模型:如图\ref{fig:Gem5_cpu},Gem5 支持多种不同的 CPU 模 型。AtomicSimpleCPU 模拟一个单周期处理器,模拟速度最 快。TimingSimpleCPU 在此之上增加对存储访问时间的模拟。O3CPU 则是一个 - 详细的乱序执行处理器模型。此外,gem5 还支持使用 KVM 虚拟化技术模 + 详细的乱序执行处理器模型。此外,Gem5 还支持使用 KVM 虚拟化技术模 拟 CPU 的执行。 -\item 系统模式:gem5 可以用系统调用模拟(SE)和全系统(FS)两种模式进行 +\item 系统模式:Gem5 可以用系统调用模拟(SE)和全系统(FS)两种模式进行 模拟,前者模拟大多数的系统调用,无需对操作系统和设备进行模拟,而后者 则模拟了操作系统和设备,同时执行用户态和内核态的指令。 -\item 存储系统:gem5 包含两种存储系统模型,来自 M5 的 Classic 模型容易 +\item 存储系统:Gem5 包含两种存储系统模型,来自 M5 的 Classic 模型容易 配置且模拟速度快,而来自 GEMS 的 Ruby 模型则提供了一个可以精确模拟缓 存一致性模型的存储系统模拟框架。 \end{enumerate} -gem5 模拟器使用 C++ 编写,并集成了 Python,模拟器的核心功能由 C++ 实现, +Gem5 模拟器使用 C++ 编写,并集成了 Python,模拟器的核心功能由 C++ 实现, 而 Python 用于初始化、配置和控制模拟器。为了支持多种指令系统和缓存一致 -性协议,gem5 分别使用了两种领域专用语言,指令系统描述语言 -和 SLICC 在gem5 构建时转为 C++ 代码并编译,生成指令系统和缓存一致性协议 +性协议,Gem5 分别使用了两种领域专用语言,指令系统描述语言 +和 SLICC 在 Gem5 构建时转为 C++ 代码并编译,生成指令系统和缓存一致性协议 的模型代码。 -最新的 gem5 还支持功耗的模拟,和 SystemC 协同模拟,同构和异构多核模拟 +最新的 Gem5 还支持功耗的模拟,和 SystemC 协同模拟,同构和异构多核模拟 等特性。 \section{论文组织结构} @@ -148,7 +148,7 @@ Spectre 攻击的各个变体。 Spectre 攻击的软硬件防御进行分析。 第四章~\nameref{sec:mywork}。提出本文所设计的防御 -Spectre 攻击的方法,并描述在 gem5 模拟器上的实现。 +Spectre 攻击的方法,并描述在 Gem5 模拟器上的实现。 第五章~\nameref{sec:eval}。对本文设计的 Spectre 防御方案,进行安全性的 验证和性能分析。 diff --git a/chap/chap2.tex b/chap/chap2.tex index 576da48..a1719ca 100644 --- a/chap/chap2.tex +++ b/chap/chap2.tex @@ -115,8 +115,6 @@ Intel 处理器,也可能可用于其他厂商的处理器。 理地址,处理器可以读取内核地址空间的数据,在产生异常前,攻击者构造的暂 态指令序列可以将读取到的数据通过隐蔽信道发送给攻击者。 -图\ref{lst:meltdown}是一段 Meltdown 攻击的示例代码,通过它可以读取内核地址空间的数据: - \begin{figure} \centering \begin{minted}{nasm} @@ -131,6 +129,7 @@ mov rbx, qword [rbx + rax] ; 访问探测数组 \label{lst:meltdown} \end{figure} +图\ref{lst:meltdown}是一段 Meltdown 攻击的示例代码,通过它可以读取内核地址空间的数据。 这段 x86 指令读取了以 rcx 为地址的内核空间的数据,在用户态下,这个读取 内核空间数据的指令会产生异常,但是在处理器产生异常之前,这条指令可以将 内核空间的数据读至寄存器,并且其后的指令也会执行,访问 rbx 指向的探测 diff --git a/chap/chap3.tex b/chap/chap3.tex index 9e49e95..19b358e 100644 --- a/chap/chap3.tex +++ b/chap/chap3.tex @@ -371,7 +371,7 @@ InvisiSpec 针对 Spectre 和 Futuristic 两种攻击模型的设计略有不同 问了这一行时,为了防止 LLC-SB 获取过时的数据,才需要使 LLC-SB 中的这一 行失效,验证和曝光操作将会从存储系统中存有最新数据的地方获取数据。 -在 gem5 模拟器下, 使用 SPEC CPU2006 和 PARSEC 对 InvisiSpec 进行评测, +在 Gem5 模拟器下, 使用 SPEC CPU2006 和 PARSEC 对 InvisiSpec 进行评测, 在 TSO 内存模型下,以 Spectre 为威胁模型,InvisiSpec 平均性能损失为 21\%,而使用 fence 性能下降 74\%. @@ -700,7 +700,7 @@ TPBuf 的结构如图 \ref{fig:tpbuf} 所示。TPBuf 的条目和装载存储队 % 检测:当传入请求进入TPbuf时,TPBuf将其PPN与现有条目的PPN进行比较,然后生成地址匹配向量(匹配)。这些矢量,包括Match,V,W和S,用作等式1逻辑的输入,以确定请求是否安全。特别地,“|”表示减少OR,它对向量中的所有位进行OR运算以生成1位输出。 %%%%%%% -在 gem5 模拟器中用 SPEC CPU2006 进行评测,使用基于缓存命中的过滤器时, +在 Gem5 模拟器中用 SPEC CPU2006 进行评测,使用基于缓存命中的过滤器时, 平均性能开销为 12.8\%,再加上 TPBuf 过滤器,平均性能开销可以再降低至 为 6.8\%. @@ -728,7 +728,7 @@ Spectre 攻击需要分为三个步骤:从存储系统装载秘密数据,将 指令执行后,执行结果将转发至后续依赖于这个指令的指令,而如果指令是访问 了敏感区域的指令,则推迟它的转发。 -在 gem5 模拟器中用 SPEC CPU2006 对几种标记方案进行评测,方案 SG(All) 标 +在 Gem5 模拟器中用 SPEC CPU2006 对几种标记方案进行评测,方案 SG(All) 标 记内存的所有页,平均性能开销为 20\%, SG(Heap) 只标记堆区域,性能开销减 少至8\%. 在使用 OpenSSL 的合成基准测试中,如果只标记私钥为秘密数据,则 性能可以接近原处理器的性能。 diff --git a/chap/chap4.tex b/chap/chap4.tex index 73ac113..b816540 100644 --- a/chap/chap4.tex +++ b/chap/chap4.tex @@ -1,11 +1,11 @@ \chapter{针对 Spectre 攻击的微体系结构设计}\label{sec:mywork} -本章讲解本文提出的一种防御 Spectre 攻击的方法,该方法使用动态信息流追 -踪的方法,检测 Spectre 组件指令流中可能泄露秘密数据的访存指令,并使用 +本章讲解本文提出的一种防御 Spectre 攻击的方法,该方法动态追踪信息流, +检测指令流中可能为 Spectre 组件中泄露秘密数据的访存指令,在此基础上,使用 一种安全的方法执行这些访存指令。 这种微体系结构设计不需要软件的支持,未修改的软件和操作系统可以直接在采用这 -种微体系结构改进的处理器中执行。 +种结构的处理器中执行。 \section{威胁模型} @@ -14,7 +14,7 @@ 本文设计的方法用于防御利用控制流推测式执行的 Spectre-PHT, Spectre-BTB, Spectre-RSB 攻击,此方法可以扩展至 Spectre-STL 攻击。攻击者在 Spectre -攻击中使用高速缓存作为隐蔽信道,其他信道不在本文的考虑范围。本文不考虑 +攻击中使用高速缓存侧信道构造隐蔽信道,其他信道不在本文的考虑范围。本文不考虑 其他的侧信道攻击。本文针对攻击者通过 Spectre 攻击获取内存中秘密数据的 情形,不考虑攻击者通过攻击获取寄存器中秘密数据的情形。 @@ -40,9 +40,10 @@ DIFT 可以作为 Spectre 攻击的检测手段之一。Spectre 的论文中指 实现了一个用于识别一条指令是否泄露数据的方法。和 TPBuf 不同的是,基 于DIFT 的方法并不检测不同的访存指令之间的地址关系,而是直接寻找读取数据 的指令和泄露数据的指令之间直接或间接的依赖关系。TPBuf 过滤器不能防范非 -共享内存区域的缓存侧信道攻击,但是基于 DIFT 的方法可以。 -而SpectreGuard\supercite{spectreguard} 中可以不依赖软件实现 -的 SG(Full)方案,目的也是阻止推测式执行中从存储系统读取的数据不被泄露, +共享内存区域的缓存侧信道攻击,但是基于 DIFT 的方法可以。同时,DIFT 的开销较小,只需要为流水线中所有产生的数据添加一个比特的标记。 + +而 SpectreGuard\supercite{spectreguard} 中可以不依赖软件实现 +的 SG(Full) 方案,目的也是阻止推测式执行中从存储系统读取的数据不被泄露, 方法是直接禁止读出的数据被后续的推测式执行的指令使用,本文的方法允许这 样的数据被使用,但是使用这个数据的指令需要用不产生侧信道的方式执行。 @@ -54,10 +55,11 @@ DIFT 可以作为 Spectre 攻击的检测手段之一。Spectre 的论文中指 手段后,可以识别出 \verb|array2[array1[x] * 4096]| 的地址依赖 于 \verb|array1[x]| 的值,从而处理器可以阻止对这个地址的访问。 -为了达到这个目的,我们为所有的物理寄存器都添加一个标记,用于表示它的值 -是否来源于推测式执行中,从内存中读出的值。在上述例子中,有一条将内 -存 \verb|array1[x]| 读取至寄存器的指令,该指令的目的寄存器的标记将会被 -设为1. +为了达到这个目的,所有在流水线中使用的数据和计算结果都需要添加一个标记, +用于表示它的值是否来源于推测式执行中,从内存中读出的值。在上述例子中, +有一个将内存 \verb|array1[x]| 读取至寄存器的指令,该指令在从存储系统中 +读取数据的同时,为这个数据添加一个标记,并将标记设为1,存放至存储该数 +据的结构,并且转发至使用该数据的指令。 \begin{figure} \begin{minted}[frame=single,linenos=true]{nasm} @@ -69,7 +71,7 @@ DIFT 可以作为 Spectre 攻击的检测手段之一。Spectre 的论文中指 movzx eax, byte [rax] shl eax, 12 lea rdx, [rip + 0x2b425d] - mov eax, dword [rdx + rax] + mov eax, [rdx + rax] loc.funcret: ret \end{minted} \caption{Spectre 组件的汇编代码} @@ -77,10 +79,10 @@ DIFT 可以作为 Spectre 攻击的检测手段之一。Spectre 的论文中指 \centering \end{figure} -上述 Spectre v1 的组件代码可以产生图\ref{lst:spectre_v1_asm}所示的指令。 -我们用表\ref{tab:spectre_dift}展示 DIFT 在推测式执行分支中的指令的行为, -其中 T 表示寄存器的标记,在分支推测式执行前,所有寄存器的标记为0,为了 -描述方便,这里用体系结构寄存器进行描述,实现中为物理寄存器的标记。 +上述 Spectre v1 的组件代码可以产生图 \ref{lst:spectre_v1_asm} 所示的指 +令。我们用表 \ref{tab:spectre_dift} 展示 DIFT 在推测式执行分支中的指令 +的行为,其中 T 表示寄存器对应的数据的标记,在分支推测式执行前,所有数 +据的标记均为0,为了描述方便,这里用体系结构寄存器进行描述,实际的微处理器中,数据可存放在物理寄存器、保留站、ROB等结构。 \begin{table} \begin{tabular}{|c|c|c|} @@ -100,7 +102,7 @@ shl eax, 12 & eax <- eax {*} 4096 & T{[}rax{]} <- T{[}rax{]} = 1\tabularnewline \hline lea rdx, {[}rip + 0x2b425d{]} & rdx <- rip + 0x2b425d & T{[}rdx{]} <- T{[}rip{]} = 0\tabularnewline \hline -\multirow{2}{*}{eax, dword {[}rdx + rax{]}} & \multirow{2}{*}{eax <- {[}rdx + rax{]}} & (T{[}rdx{]} | T{[}rax{]}) = 1, 指令不安全 \tabularnewline +\multirow{2}{*}{mov eax, {[}rdx + rax{]}} & \multirow{2}{*}{eax <- {[}rdx + rax{]}} & (T{[}rdx{]} | T{[}rax{]}) = 1, 指令不安全 \tabularnewline \cline{3-3} & & T{[}rax{]} <- 1\tabularnewline \hline @@ -112,42 +114,42 @@ lea rdx, {[}rip + 0x2b425d{]} & rdx <- rip + 0x2b425d & T{[}rdx{]} <- T{[}rip{]} 以下描述这个检测方法的具体细节。 -标记的设置:在推测式执行时,对于所有从内存读取数据的指令,将其所有目的 -寄存器的标记设为1. +标记的设置:在推测式执行时,对于所有从内存读取数据的指令,读取的数据均 +标记为1. 标记的传播:标记的传播在处理器的执行阶段进行,在这个阶段,处理器在读源 -寄存器的同时,将它们对应的标记读出。对于不同类型的指令,标记传播的方式 -如下: +操作数的同时,将它们对应的标记读出。对于立即数和非流水线中产生的数据, +如直接从寄存器中读取的数据,标记均为0。对于不同类型的指令,标记传播的 +方式如下: \begin{itemize} -\item 对于算术类指令,它的源操作数均来源于寄存器,其目的寄存器的标记设 - 为所有源寄存器标记做或运算的结果。 +\item 对于算术类指令,它的源操作数均为寄存器操作数或立即数操作数,计算 + 结果的标记设为所有源寄存器操作数对应的数据的标记做或运算的结果。 \item 对于装载类指令,它从内存中读取数据,这是标记设置的基本条件,因此 - 目的寄存器的标志设为1. -\item 对于存储类指令,它没有目的寄存器。和一般的 DIFT 实现不同,我们不 - 对任何内存进行标记。因为要使用存入内存中的数据,需要有一套指令将其重 - 新从内存中读出,这个操作会设置这条指令目的寄存器的标记。 -\item 对于转移类指令,我们为每个指令添加一位标记,如果源寄存器中有标记 - 为1的指令,则设置这个指令的标记为1,否则设置为0.转移指令的的标记将在 + 计算结果的标志设为1. +\item 对于存储类指令,它没有目的寄存器。和一般的 DIFT 实现不同,用于检 + 测 Spectre 组件中泄露数据的指令的 DIFT 过程不对任何内存进行标记,因 + 为要使用存入内存中的数据,需要有一个指令将其重新从内存中读出,这个操 + 作会设置这条指令产生的结果的标记。 +\item 对于控制类指令,我们为每个指令添加一位标记,如果源操作数中有标记 + 为1的指令,则设置这个指令的标记为1,否则设置为0.控制指令标记的功能将在 下文描述。 \end{itemize} 标记的清除:当一条指令不再处于推测式执行的状态,即该指令此前的所有分支 -都执行完成并通过验证,则要将这条指令所有目的寄存器的标记重置为0.对于转 -移类指令,则清除该转移指令的标记。 +都执行完成并通过验证,则要将这条指令所有产生的结果的标记重置为0.对于控 +制类指令,则清除该控制指令的标记。 -寄存器中的标记可以处理读取内存中数据的指令,和泄露内存中数据的指令,存 -在直接或间接数据相关的情形。读取内存的指令使得存放它的寄存器被标记,此 -后和它存在直接或间接数据相关的指令,会将这个标记传播至这些指令的目的寄 -存器。 +流水线中数据的标记可以处理从内存中读取的数据,和泄露内存中数据的指令, +存在直接或间接数据相关的情形。读取内存的指令使得读出的数据被标记,此后 +和它存在直接或间接数据相关的指令,会将这个标记传播至这些指令的计算结果。 -考虑攻击者在 Spectre 攻击中利用缓存侧信道泄露内存中的数据,则 +考虑攻击者在 Spectre 攻击中利用缓存侧信道泄露内存中数据的情形, 在 Spectre 的组件代码中,泄露数据的指令为装载指令,该装载指令的地址直接 或间接依赖于内存中的数据。在加入上述的 DIFT 检测机制后,由于该装载指令 -依赖于内存中的数据,它必定有一个被标记的源寄存器,从而处理器可以得知该 -指令不安全。 +依赖于内存中的数据,它必定有一个源寄存器,对应的在流水线中的数据被标记,从而处理器可以得知该指令不安全。 -转移指令的标记用于处理可能泄露数据的指令,和内存中数据的值存在控制相关 +控制指令的标记用于处理可能泄露数据的指令,和内存中数据的值存在控制相关 的情形,如图\ref{lst:victim_v10}的例子\supercite{msvc}: \begin{figure}[htbp] @@ -168,33 +170,34 @@ void victim(size_t x, uint8_t k) { 果两个值相等,则会访问 \verb|array2[0]|,即访问 \verb|array2[0]| 的指令 和访问 \verb|array1[x]| 的指令存在控制相关,攻击者可以通过探 测\verb|array2[0]| 是否在缓存中,判断 \verb|array1[x]| 的值是否 -和\verb|k| 相等。只使用寄存器的标记,并不能检测出读取 \verb|array2[0]| +和 \verb|k| 相等。只对数据进行标记,并不能检测出读取 \verb|array2[0]| 的指令和 \verb|array1[x]| 的值存在依赖关系。 -因此我们需要转移指令中的标记。如果一条指令在被标记的转移指令之后执行, -则该指令和一个被标记的数据存在依赖关系,如果指令为装载指令,由于它改变 +因此这个 DIFT 方案需要控制指令中的标记。如果一条指令在被标记的控制指令之后执行, +则该指令和一个被标记的数据存在控制依赖关系,如果指令为装载指令,由于它改变 了缓存的状态,攻击者可以通过缓存信道得知该指令被执行过,推测出被标记转 移指令的执行结果,从而推测出内存中秘密数据的值,因此这样的装载指令也是 不安全的指令。 -这种检测方案的微体系结构实现如图\ref{fig:spectre_dift}所示。 - -\begin{figure}[htbp] - \centering - \includegraphics[width=0.8\textwidth]{spectre_dift.eps} - \caption{基于 DIFT 的 Spectre 检测方法的微体系结构示意图} - \label{fig:spectre_dift} -\end{figure} +%这种检测方案的微体系结构实现如图\ref{fig:spectre_dift}所示。 +% +%\begin{figure}[htbp] +% \centering +% \includegraphics[width=0.8\textwidth]{spectre_dift.eps} +% \caption{基于 DIFT 的 Spectre 检测方法的微体系结构示意图} +% \label{fig:spectre_dift} +%\end{figure} \section{不安全指令的执行方式} -对于检测到的不安全的指令,最简单的方式是阻止它的执行,直到指令因推测式 +对于检测到的不安全的指令,最简单的方式是推迟它的执行,直到指令因推测式 执行错误回卷,或确认为安全状态,再重新调度至执行单元执行。这种做法会导 致推测式执行中,后续所有依赖于这条指令的指令都会被推迟,降低流水线的利 用率,导致性能下降。 -一种方法是使用 InvisiSpec \supercite{invisispec},和 Spectre 攻击的检测 -机制结合后,可以作为单条不安全指令的执行机制。它将不安全指令从内存中读 +InvisiSpec\supercite{invisispec} 是使用临时结构存放推测式执行中读取的 +数据,从而防止暂态访存指令结果泄露的方法。和 Spectre 攻击的检测机制结 +合后,可以作为单条不安全指令的执行机制。这种方法将不安全指令从内存中读 到的数据放入推测式执行缓冲区中,后续的指令可以使用这条指令的执行结果, 确保指令流的继续执行。在推测式执行错误时,推测式执行缓冲区的内容会被丢 弃,缓存状态不会改变,因此不会产生侧信道。推测式执行被验证为安全时,缓 @@ -208,64 +211,67 @@ void victim(size_t x, uint8_t k) { 大。这种方法和 Conditional Speculation \supercite{conditional-speculation} 中的基于缓存命中的过滤器基本相同。 -\section{针对 Spectre 攻击的微体系结构在 gem5 中的实现} +本文使用的方案是使用 InvisiSpec 作为不安全的指令的执行机制,它可以保证 +在执行装载指令时,无论它是否命中缓存,都可以获取数据,使得依赖于它的指 +令可以继续执行。作为对比,本文同时评估了推迟指令执行的方式。 + +\section{针对 Spectre 攻击的微体系结构在 Gem5 中的实现} -以下介绍这种可抵抗 Spectre 攻击的微体系结构在 gem5 模拟器中的实现。首先分 -析 gem5 中乱序执行处理器的实现,然后分别介绍 InvisiSpec 和本文使用的 -DIFT 方案在 gem5 中的实现。 +以下介绍这种针对 Spectre 攻击的结构在 Gem5 模拟器中的实现。首先分析 +Gem5 中乱序执行处理器的实现,然后分别介绍 InvisiSpec 和本文使用的 DIFT +方案在 Gem5 中的实现。 -\subsection{gem5 的乱序执行处理器} +\subsection{Gem5 的乱序执行处理器} -%\Todo: 做一个 gem5 流水线的示意图? +%\Todo: 做一个 Gem5 流水线的示意图? -gem5 的乱序执行处理器实现在 FullO3CPU 类中,它又用类实现类处理器的以下 +Gem5 的乱序执行处理器实现在 FullO3CPU 类中,它又用不同的类实现处理器的以下 流水级:取指(Fetch)、译码(Decode)、重命名(Rename)、发射/执行/回 写(IEW)、提交(Commit)。 -gem5 的取指和译码阶段由 DefaultFetch 和 DefaultDecode 两个类实现。在 -DefaultFetch 中,取指部件从指令缓存中取出处理器 PC 位置的指令,并用指 +Gem5 的取指和译码阶段由 DefaultFetch 和 DefaultDecode 两个类实现。在 +DefaultFetch 中,取指部件从指令缓存中取出处理器程序计数器(PC)位置的指令,并用指 令系统对应的译码器进行译码,再取出指令对应的微指令,将微指令传至译码阶 段,译码阶段再将其传到重命名阶段。取指阶段取出的指令在 DynInst 类的实 例中保存。 -gem5 的重命名阶段由 DefaultRename 类实现,它对指令的源寄存器和目的寄存 +Gem5 的重命名阶段由 DefaultRename 类实现,它对指令的源寄存器和目的寄存 器进行重命名。重命名后,指令的 DynInst 实例中的源寄存器和目的寄存器均 保存它们对应的物理寄存器,同时还保存目的寄存器原来对应的物理寄存器用于 恢复。 -gem5 的发射、执行和回写三个阶段由一个类 DefaultIEW 实现,它模拟了处理 -器将指令发射至功能单元和处理器执行指令的过程。gem5 中用一个专门的语言 +Gem5 的发射、执行和回写三个阶段由一个类 DefaultIEW 实现,它模拟了处理 +器将指令发射至功能单元和处理器执行指令的过程。Gem5 中用一个专门的语言 定义了每个指令系统的指令的语义,为每个指令和微指令生成一个 StaticInst -类,里面定义了指令的执行方式。对于存储访问类指令,gem5 用 LSQ 类定义处 +类,里面定义了指令的执行方式。对于存储访问类指令,Gem5 用 LSQ 类定义处 理器中的装载和存储指令队列,这些指令在执行时添加至队列中,进行存储访问 操作。 -gem5 的提交阶段由 DefaultCommit 类实现,它提交 ROB 队列头部的指令,更 +Gem5 的提交阶段由 DefaultCommit 类实现,它提交 ROB 队列头部的指令,更 新 ROB 的状态。 \subsection{安全执行装载指令方案的实现} -图\ref{fig:load_exec}是 gem5 中执行一条装载指令的总体流程。 - \begin{figure}[htbp] \centering \includegraphics[width=0.8\textwidth]{load_exec.eps} - \caption{gem5 O3CPU 执行装载指令的过程} + \caption{Gem5 O3CPU 执行装载指令的过程} \label{fig:load_exec} \end{figure} -在执行阶段,处理器将装载指令传递至 LSQ,装载指令将会按序进入 LQ. gem5 +图 \ref{fig:load_exec} 是 Gem5 中执行一条装载指令的总体流程。 +在执行阶段,处理器将装载指令传递至 LSQ,装载指令将会按序进入 LQ. Gem5 用指令系统特定的 initiatAcc 方法模拟该指令系统中装载指令访问存储系统的 方式。最后 LSQ 将装载指令的信息封装为一个请求,用 sendTimingReq 将这个 请求发送至存储系统。 发送至存储系统的读请求并不会立刻得到结果,需要等待来自存储系统的响应。 -图\ref{fig:load_exec}的右半部分是处理器接收响应的流程, +图 \ref{fig:load_exec} 的右半部分是处理器接收响应的流程, 在 recvTimingResp 后,处理器可以得到此前发送的请求对应的结果,根据得到 的结果,LSQ 执行回写操作,将结果写入至指令的目的寄存器,并将指令送至提 交阶段,完成指令的执行。 -对于不安全指令的执行,可以为其增加一种 SpecLoad 请求,不同于普通的Load +对于不安全指令的执行,可以为其增加一种 SpecLoad 请求,不同于普通的 Load 请求,SpecLoad 执行后,不会改变任何缓存状态和缓存一致性状态,因此不会留 下缓存的侧信道。 @@ -275,12 +281,12 @@ gem5 的提交阶段由 DefaultCommit 类实现,它提交 ROB 队列头部的 证 SpecLoad 读取的结果正确,或直接确认 SpecLoad 的结果,因此还需要再增 加一个 Expose 请求,用于确认或验证结果。 -在 gem5 中,多核系统的缓存和缓存一致性模型由 Ruby 存储系统模拟。本文模 -拟一个带二级缓存的处理器,缓存一致性协议为 MESI,需要修改的相关文件 +在 Gem5 中,多核系统的缓存和缓存一致性模型由 Ruby 存储系统模拟。本文模 +拟一个带二级缓存的处理器,缓存一致性协议为 MESI,Gem5 中相关文件 为 src/mem/protocol 下以 MESI\_Two\_Level 开头的文件。 -对于一级缓存,为了增加对不安全内存读取的支持,我们修改状态机文 -件 MESI\_Two\_Level-L1cache.sm. 除了添加 SpecLoad 和 Expose 两个请求外, +对于一级缓存,为了增加对不安全内存读取的支持,可以在状态机文 +件 MESI\_Two\_Level-L1cache.sm 中添加所需的请求和操作。除了添加 SpecLoad 和 Expose 两个请求外, 还要处理从其他处理器转发的响应的请求。此外,在处理器的实现中,状态机接 收到处理器的请求,到从存储系统得到数据之间,状态机处于一个过渡状态,因 此在状态机中添加一个状态 IX,表示接收了 SpecLoad 之后缓存缺失,向下级存 @@ -317,8 +323,8 @@ InvisiSpec 中,一级缓存处理 SpecLoad 和 Expose 的部分状态如 \subsection{执行流水线的修改} -我们在 DynInst 类为指令添加新的状态和属性,添加的主要的指令状态和属性 -见表\ref{tab:inst_status}。 +为了维护指令的安全、推测式内存读取等信息,需要在 DynInst 类为指令添加 +新的状态和属性,添加的主要的指令状态和属性见表\ref{tab:inst_status}。 \begin{table} \begin{tabular}{|p{0.25\textwidth}|p{0.75\textwidth}|} @@ -363,8 +369,8 @@ PrevBrsResolved 状态。在 LSQ 中,对于每一个未完成的装载指令 之前是否存在未决分支,判断指令是否安全,设定 ReadyToExpose 属性,取消 FenceDelay 标志。 -执行单元执行一条装载指令时,根据 ReadyToexpose 属性判断是否需要用 -InvisiSpec 等安全的方式执行。修改后的执行流程如图\ref{fig:is-load}, +执行单元执行一条装载指令时,根据 ReadyToExpose 属性判断是否需要用 +InvisiSpec 等安全的方式执行。修改后的执行流程如图 \ref{fig:is-load}, LSQ 每周期都要将已转为安全指令的装载指令的验证或曝光,发送请求的 LSQUnit::read 过程需要支持 SpecLoad 请求的发送,对地址翻译的过程做一个 微小的修改,对 TLB 不命中的推测式执行的指令要延迟执行,防止产生 TLB 的 @@ -372,7 +378,7 @@ LSQUnit::read 过程需要支持 SpecLoad 请求的发送,对地址翻译的 \begin{figure}[htbp] \centering - \includegraphics[width=0.8\textwidth]{is-load.eps} + \includegraphics[width=0.6\textwidth]{is-load.eps} \caption{安全执行指令的流程} \label{fig:is-load} \end{figure} @@ -380,14 +386,19 @@ LSQUnit::read 过程需要支持 SpecLoad 请求的发送,对地址翻译的 \subsection{动态信息流追踪的实现} 动态信息流追踪的实现分为标记设置、传播、清除和使用四个部分,以下分别介 -绍它们在 gem5 中的实现。 +绍它们在 Gem5 中的实现。 + +Gem5 的处理器模型使用显式寄存器重命名机制,Gem5 模拟指令执行后,结果均 +存放在物理寄存器中,此后执行阶段将指令目的寄存器结果可用的信息,通知至 +相关的指令。因此,在 Gem5 中模拟 DIFT,只需要为所有物理寄存器添加一个 +对应的标记。 对所有推测式执行中的装载指令,其目的寄存器都需要设置标记。在扫描 LSQ 中指令的时候,指令前存在未决分支,则对这个指令的目的寄存器设置标记。 标志的传播在执行阶段进行。对于非访存类指令,如果指令有设置了标记的源寄 存器,则设置该指令的目的寄存器的标记。同时也设置指令的 IsTainted 属性, -它作为转移指令的标记。 +它作为控制指令的标记。 指令的 IsTainted 属性和目的寄存器的标记在更新 ROB 中每条指令 的 PrevBrsResolved 状态的时候清除,这个过程同时更新指令 @@ -401,6 +412,6 @@ LSQUnit::read 过程需要支持 SpecLoad 请求的发送,对地址翻译的 \section{小结} 本章前两节介绍本文设计的基于信息流追踪的 Spectre 组件的检测方法,讨论 -了执行可能泄露数据的装载指令的几种方法。第三节介绍了在 gem5 中实现这些 -技术的方法,包括对 gem5 流水线的分析,gem5 装载指令执行流程的分析,对 +了执行可能泄露数据的装载指令的几种方法。第三节介绍了在 Gem5 中实现这些 +技术的方法,包括对 Gem5 流水线的分析,Gem5 装载指令执行流程的分析,对 执行流水线作出的修改,实现装载指令安全执行的方法。 diff --git a/chap/chap5.tex b/chap/chap5.tex index 2c83fe3..f4474ec 100644 --- a/chap/chap5.tex +++ b/chap/chap5.tex @@ -4,18 +4,18 @@ \section{评测环境} -本文对 gem5 模拟器修改,对以下 5 种配置进行评测:Baseline, Fence, +本文对 Gem5 模拟器修改,对以下 5 种配置进行评测:Baseline, Fence, Fence+DIFT, IS, IS+DIFT. Baseline 表示受 Spectre 攻击影响的处理器模型, Fence 和 IS 分别表示对所有推测式执行中的装载指令,推迟执行和用 -InvisiSpec的方案执行,Fence+DIFT 和 IS+DIFT 则是使用动态信息流追踪识别 +InvisiSpec 的方案执行,Fence+DIFT 和 IS+DIFT 则是使用动态信息流追踪识别 可能泄露秘密数据的装载指令,只对这些装载使用相应的安全的执行方案。 -表\ref{tab:gem5_conf}中列出了所有处理器配置的基本配置。 +表\ref{tab:Gem5_conf}中列出了所有处理器配置的基本配置。 \begin{table} \centering \caption{模拟的处理器的基本配置} -\label{tab:gem5_conf} +\label{tab:Gem5_conf} \begin{tabular}{|c|c|} \hline 参数 & 配置 \tabularnewline @@ -69,12 +69,12 @@ L2 Cache & 2MB, 16路组相联, 8周期延迟\tabularnewline 体系结构设计运行基准程序,和 Baseline 的运行时间的比值,平均性能取这些 比值的几何平均数。 -\subsection{功能验证} +\section{功能验证} 本文构造一个测试程序对每种配置的处理器进行安全性的测试,用于验证实现的 方案可以防御 Spectre 攻击。 -由于 gem5 的 Ruby 存储模型不支持 clflush 指令,因此测试程序使 +由于 Gem5 的 Ruby 存储模型不支持 clflush 指令,因此测试程序使 用Evict+Reload 的方式进行攻击。由于配置的系统末级缓存为 2MB,可以对一 个2MB 的存储区域进行访问,以清除缓存内原有内容,具体代码可 见附件\ref{lst:poc_for_gem5}。 @@ -95,8 +95,8 @@ L2 Cache & 2MB, 16路组相联, 8周期延迟\tabularnewline 集。所有的基准程序均用 GCC 8.3.0 编译,编译优化选项为 -O2,并且和 Glibc 2.24 静态链接。 -由于 gem5 模拟器运行 SPEC CPU2006 所需时间过长,因此评测时选取部分指令, -方法是先用 gem5 的 AtomicSimpleCPU 运行 10000000000 条指令进行程序的预 +由于 Gem5 模拟器运行 SPEC CPU2006 所需时间过长,因此评测时选取部分指令, +方法是先用 Gem5 的 AtomicSimpleCPU 运行 10000000000 条指令进行程序的预 热,再用待评测的处理器配置运行 1000000000 条指令,得出评测结果。 %% 表\ref{tab:spec2006}中列出每个 SPEC CPU2006 在 Baseline 模式下运行的指 @@ -156,7 +156,7 @@ Glibc 2.24 静态链接。 %% \label{tab:spec2006} %% \end{table} -图\ref{fig:is_spec06_result}是每种配置的处理器运行 SPEC CPU2006 相对于 +图 \ref{fig:is_spec06_result} 是每种配置的处理器运行 SPEC CPU2006 相对于 Baseline 的运行时间。其中 cactusADM 和 lbm 由于每种配置的相对运行时间 都接近 1,故未列入图中。 @@ -236,8 +236,8 @@ Baseline 的运行时间。其中 cactusADM 和 lbm 由于每种配置的相对 %% \end{table} %% 为了观察使用基于信息流追踪的检测机制的效果,可以统计 IS 和 IS+DIFT 方 -案中 SpecLoad 请求的数量。图\ref{fig:specload}列出两种方案中,SpecLoad -请求的数量和程序的总操作数(gem5 模拟后得出的 sim\_ops 结果)的比例。 +案中 SpecLoad 请求的数量。图 \ref{fig:specload} 列出两种方案中,SpecLoad +请求的数量和程序的总操作数(Gem5 模拟后得出的 sim\_ops 结果)的比例。 可以看出,几乎所有的基准程序中,DIFT 可以过滤一半以上被认为不安全的装 载操作,其中 bwaves, GemsFDTD, libquantum, milc 中,推测式执行中的装载 diff --git a/chap/chap6.tex b/chap/chap6.tex index cedcc8b..f49d8fd 100644 --- a/chap/chap6.tex +++ b/chap/chap6.tex @@ -17,10 +17,10 @@ 和软硬件结合的防御方法。其中最重要的是硬件防御方法,主要介 绍InvisiSpec 和 Conditional Speculation 两种,并分析了各种防御方案设 计特点,可防御的攻击种类,和它们的优缺点。 -\item 设计一种防御防御 Spectre 攻击的微架构,并在 gem5 中进行实现。这种 +\item 设计一种防御防御 Spectre 攻击的微架构,并在 Gem5 中进行实现。这种 防御方案利用动态信息流追踪技术检测指令流中可能被用于 Spectre 攻击泄露 数据的装载指令,并采用 InvisiSpec 方案执行检测为不安全的装载指令。 -\item 最后对实现的 Spectre 防御方案进行评估,首先构造了一个能用于 gem5 +\item 最后对实现的 Spectre 防御方案进行评估,首先构造了一个能用于 Gem5 的概念性验证程序,用于测试所实现的微架构的安全性。为了评估这种微架构 的性能开销,使用 SPEC CPU2006 评测了这种微架构的性能,和原有的不安全 的处理器相比,性能开销为 8.5\%,优于只用 InvisiSpec 执行推测式执行的 diff --git a/chap/encl1.tex b/chap/encl1.tex index 6a8e62a..0c47c6e 100644 --- a/chap/encl1.tex +++ b/chap/encl1.tex @@ -3,7 +3,10 @@ \chapter{附件} -\section{在 gem5 中验证处理器模型安全性的代码}\label{lst:poc_for_gem5} +\section{在 Gem5 中验证处理器模型安全性的代码}\label{lst:poc_for_gem5} + +以下 C 程序使用 Evict+Reload 的方式对受害者函数 victim 进行 Spectre 攻击。 +对于不安全的处理器模型,运行该程序时,数据 X 对应的行(以下程序为123)会输出 hit,其他行均输出 miss. 而安全的处理器模型中,所有行均输出 miss. \begin{minted}{C} #include -- cgit v1.2.3