summaryrefslogtreecommitdiff
path: root/chap/chap4.tex
blob: 455e2b60c9c65068b7e2f067470843c8f458681e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
\chapter{针对 Spectre 攻击的微架构设计}\label{sec:mywork}

本章讲解本文提出的一种防御 Spectre 攻击的方法,该方法使用动态信息流追
踪的方法,检测 Spectre 组件指令流中可能泄露秘密数据的访存指令,并使用
InvisiSpec 的方法执行这些访存指令。

%这个设计有如下特点:
%\begin{itemize}
%\item 它不需要任何软件修改
%\item 

\section{威胁模型}

本文对攻击者做如下假设:攻击者知道受害者程序的代码、进程中的地址分布信
息,攻击者和受害者可以在同一进程,共享同一处理器核,或在不同处理器核上。

本文设计的方法用于防御利用控制流推测式执行的 Spectre-PHT, Spectre-BTB,
Spectre-RSB 攻击,此方法可以扩展至 Spectre-STL 攻击。攻击者在 Spectre
攻击中使用高速缓存作为隐蔽信道,其他信道不在本文的考虑范围。本文不考虑
其他的侧信道攻击。本文针对攻击者通过 Spectre 攻击获取内存中秘密数据的
情形,不考虑攻击者通过攻击获取寄存器中秘密数据的情形。

\section{基于动态信息流追踪的Spectre检测方法}

\Todo: 这一节是否可以写到3页?

动态信息流追踪(Dynamic Information Flow Tracking)\supercite{dift}是
一种硬件安全策略,通过识别可疑的信息流,并限制可疑信息的使用,保护程序
的安全。它最早用于防止攻击者利用缓冲区溢出攻击执行恶意代码,也可以用于
检测跨站脚本攻击、SQL注入等攻击。\supercite{raksha}

DIFT 可以作为 Spectre 攻击的检测手段之一。Spectre 的论文中指出处理器可
以追踪数据是否在推测式执行中获取,进而阻止在后续可能泄露这个数据的操作
中使用,作为阻止数据进入隐蔽信道的方法。\supercite{spectre}
CSF\supercite{context-sensitive-fencing} 中的译码级信息流追踪框架 DIFT,
用于追踪处理器使用的数据是否来源于用户输入,从而处理器可以根据此信息判
断是否需要插入 fence 微码。OISA\supercite{oisa} 在指令系统的定义中即包
含了 DIFT 技术,用于追踪一个数据是否为秘密数据。

本文使用 DIFT 检测 Spectre 组件中泄露数据的 load 指令。详细设计如下:

\Todo: 解释为什么使用这种方法,和其他相似方法(DLIFT, TPBuf, SG(Full))的比较

\Todo: 增加结构示意图和代码描述

\Todo: 使用更加详细的描述

\begin{itemize}
\item 为每个物理寄存器添加一位标记,表示这个寄存器的数据是否来自于推测
  式执行中从内存读取的数据
\item 如果在推测式执行中,一条指令从内存中读取了数据,则设置这条指令的
  目的寄存器的标志为1
\item 对于非访存指令,如果存在标记为1的源寄存器,则设置这条指令的目的
  寄存器标志为1,否则设置标志为0
\item 当一条指令之前所有分支指令执行完成,确认推测式执行正确后,设置这
  条指令的目的寄存器标志为0
\item 在推测式执行的过程中执行 load 指令时,如果存在标记为1的源寄存器,
  则这条指令为不安全的 load
\end{itemize}

以上 DIFT 实现只考虑了泄露的 load 指令和读取秘密数据的 load 指令存在数
据相关,此外还要考虑控制相关的情形,如以下例子\supercite{msvc}:

\begin{minted}{C}
void victim(size_t x, uint8_t k) {
     if (x < array1_size) {
          if (array1[x] == k)
               temp &= array2[0];
     }
}
\end{minted}

这个例子读取的 \verb|array1[x]| 和攻击者猜测的值 \verb|k| 进行比较,如
果两个值相等,则会访问 \verb|array2[0]|,即访问 \verb|array2[0]| 的指
令和访问 \verb|array1[x]| 的指令存在控制相关,对 \verb|array2[0]| 的访
问可能泄露 \verb|array1[x]| 的数据。因此,如果一条控制指令依赖于被标记
的寄存器,则对它进行标记,其后的所有 load 指令都认为不安全。

\Todo: 解释怎样处理以上的情形

\section{使用推测式执行缓冲区}

\Todo: 说明在检测到不安全的访存指令后,推迟它的执行和用 InvisiSpec 的 SpecBuf 执行的区别

\Todo: 为什么只对部分指令使用,对推测式执行中的部分指令使用 InvisiSpec 是否需要修改

\Todo: 本文使用的基于 DIFT 的检测方法和 InvisiSpec 结合

\section{针对 Spectre 攻击的微架构在 gem5 中的实现}

\Todo: 这节介绍怎样在 gem5 中实现我的工作

以下介绍这种可抵抗 Spectre 攻击的微架构在 gem5 模拟器中的实现。首先分
析 gem5 中乱序执行处理器的实现,然后分别介绍 InvisiSpec 和本文使用的
DIFT 方案在 gem5 中的实现。

\subsection{gem5 的乱序执行处理器}

\Todo: 做一个 gem5 流水线的示意图?

gem5 的乱序执行处理器实现在 FullO3CPU 类中,它又用类实现类处理器的以下
流水级:取指(Fetch)、译码(Decode)、重命名(Rename)、发射/执行/回
写(IEW)、提交(Commit)。

gem5 的取指和译码阶段由 DefaultFetch 和 DefaultDecode 两个类实现。在
DefaultFetch 中,取指部件从指令缓存中取出处理器 PC 位置的指令,并用指
令系统对应的译码器进行译码,再取出指令对应的微指令,将微指令传至译码阶
段,译码阶段再将其传到重命名阶段。取指阶段取出的指令在 DynInst 类的实
例中保存。

gem5 的重命名阶段由 DefaultRename 类实现,它对指令的源寄存器和目的寄存
器进行重命名。重命名后,指令的 DynInst 实例中的源寄存器和目的寄存器均
保存它们对应的物理寄存器,同时还保存目的寄存器原来对应的物理寄存器用于
恢复。

gem5 的发射、执行和回写三个阶段由一个类 DefaultIEW 实现,它模拟了处理
器将指令发射至功能单元和处理器执行指令的过程。gem5 中用一个专门的语言
定义了每个指令系统的指令的语义,为每个指令和微指令生成一个 StaticInst
类,里面定义了指令的执行方式。对于存储访问类指令,gem5 用 LSQ 类定义处
理器中的装载和存储指令队列,这些指令在执行时添加至队列中,进行存储访问
操作。

gem5 的提交阶段由 DefaultCommit 类实现,它提交 ROB 队列头部的指令,更
新 ROB 的状态。

\subsection{InvisiSpec的LSQ的实现}

\Todo: InvisiSpec 所用的 load 指令执行逻辑在 gem5 LSQ 中的实现

\subsection{推测式执行缓冲区的实现}

\Todo: InvisiSpec 的 SpecBuf 在 gem5 中的实现

\subsection{InvisiSpec对缓存一致性协议的修改}

\Todo: InvisiSpec 的 SpecBuf 在 gem5 中的实现

\subsection{动态信息流追踪的实现}

\Todo: 本文所用的 DIFT 方案在 gem5 中的实现,和已有 InvisiSpec 代码的结合

\Todo: 如何添加一个总结性的章节?