\chapter{评测}\label{sec:eval} \section{评测环境} 本文对 gem5 模拟器修改,对以下 5 种配置进行评测:Baseline, Fence, Fence+DIFT, IS, IS+DIFT. Baseline 表示受 Spectre 攻击影响的处理器模型, Fence 和 IS 分别表示对所有推测式执行中的 load 指令,推迟执行和用 InvisiSpec的方案执行,Fence+DIFT 和 IS+DIFT 则是使用动态信息流追踪识别 可能泄露秘密数据的 load,只对这些 load 使用相应的安全的执行方案。 对所有的处理器配置,基本配置如下: \begin{tabular}{|c|c|} \hline 参数 & 配置 \tabularnewline \hline \hline 指令系统 & x86\_64\tabularnewline \hline 处理器类型 & 8发射乱序处理器\tabularnewline \hline ROB & 192\tabularnewline \hline LDQ & 32\tabularnewline \hline STQ & 32\tabularnewline \hline 发射队列 & 64\tabularnewline \hline L1 I-Cache & 32KB, 4路组相联, 1周期延迟\tabularnewline \hline L1 D-Cache & 64KB, 8路组相联, 1周期延迟\tabularnewline \hline L2 Cache & 2MB, 16路组相联, 8周期延迟\tabularnewline \hline \end{tabular} \section{评测指标} \section{评测结果} \subsection{微架构安全性测试} 本文构造一个测试程序对每种配置的处理器进行安全性的测试,用于验证实现的 方案可以防御 Spectre 攻击。 由于 gem5 的 Ruby 存储模型不支持 clflush 指令,因此测试程序使用 Evict+Reload 的方式进行攻击。由于配置的系统末级缓存为 2MB,可以对一个 2MB 的存储区域进行访问,以清除缓存内原有内容。 具体代码如下: \begin{minted}{C} #include #include #include #include /* default: 64B line size, L1-D 64KB assoc 2, L1-I 32KB assoc 2, L2 2MB assoc 8 */ #define LLC_SIZE (2 << 20) uint8_t dummy[LLC_SIZE]; size_t array_size = 4; uint8_t array1[200] = {1, 2, 3, 4}; uint8_t array2[256 * 64 * 2]; uint8_t X; uint8_t array3[4096]; uint8_t tmp; uint8_t victim(size_t idx) { if (idx < array_size) { return array2[array1[idx] * 64]; } return 0; } int main() { unsigned long t[256]; volatile uint8_t x; victim(0); victim(0); victim(0); victim(0); victim(0); memset(dummy, 1, sizeof(dummy)); // flush L2 X = 123; // set the secret value, and also bring it to cache _mm_mfence(); size_t attack_idx = &X - array1; victim(attack_idx); for (int i = 0; i < 256; i++) { unsigned int junk; unsigned long time1 = __rdtscp(&junk); x ^= array2[i * 64]; unsigned long time2 = __rdtscp(&junk); t[i] = time2 - time1; } printf("attack_idx = %ld\n", attack_idx); for (int i = 0; i < 256; i++) { printf("%d: %d, %s\n", i, t[i], (t[i] < 40)? "hit": "miss"); } } \end{minted} 在以上代码中,攻击者要通过受害者执行的函数 victim 的推测式执行泄露 victim 在正常执行中无法访问的 X 的值。攻击者先训练 victim 的分支预测器, 清除缓存中原有的内容,之后我们设置 X 为 123,然后攻击者再让 victim 执 行访问 X,最后扫描 array2 检查其中是否有元素在缓存中命中。 在 Baseline 配置中,执行上述程序,可以看到 \verb|array2[123 * 64]| 在 缓存中命中,在 array2 的其他位置缓存缺失,从而攻击者可以通过 Spectre 攻击得到 X 的值 123. 而在其他配置中,array2 的所有位置都发生缓存缺失, 从而攻击者无法得出 X 的值,说明这些配置都能防御 Spectre 攻击。 \subsection{SPEC CPU2006的性能评测} 本文对 21 个 SPEC CPU2006 基准测试进行评测,基准测试的数据集使用 ref 集。先用 gem5 的 AtomicSimpleCPU 运行 10000000000 条指令,再用待评测的 处理器配置运行 1000000000 条指令,得出评测结果。 \begin{figure}[htbp] \centering \includegraphics[width=0.8\textwidth]{result.eps} \end{figure} 从评测结果可以看出,在使用 DIFT 识别可能泄露数据的 load 指令后,推迟这 些指令的执行,有 15\% 的性能开销,平均性能开销比 InvisiSpec 小。在此基 础上,用 InvisiSpec 的方案执行这些 load 指令,可以进一步将性能开销减少 至 8.5\%. \Todo: 评测结果的分析