[toc]

概要

Meltdown/Spectre被发现于2018年, 是很有影响力的cpu漏洞。

Meltdown(熔断)对应编号恶意数据缓存加载 CVE-2017-5754 。

Spectre (幽灵)对应编号边界检查绕过 CVE-2017-5753 、分支目标注入 CVE-2017-5715 。

Meltdown 影响几乎所有的 Intel CPU(从1995年起)以及部分 ARM CPU。 Spectre 拥有更广的影响范围,在 Meltdown 的情况下,恶意程序可读取某些自身无权限访问的数据。利用此漏洞低权限用户可以访问到本身无权限访问的内容,例如用户密码、加密密钥。

Spectre 恶意利用程序,可导致用户的帐号、密码泄漏。在公共云服务器上,可能打破界限,从一台虚拟机器获取到另一个用户的权限。

名词

指令周期:CPU取出一条指令并执行该指令所需的时间称为指令周期,指令周期的长短与指令的复杂程度有关,一般多个CPU周期组成指令周期。

CPU周期:又称机器周期,通常用从主存读取一条指令的最短时间来规定CPU周期,一般多个时钟周期组成CPU周期

时钟周期:时钟周期是处理操作的最基本时间单位,由机器的主频决定(超到20GHZ,全人类感谢你)

CPU的执行

基本过程

img

cpu一般按照 取指令–>指令译码—>指令执行–>存储访问–>写回

1
2
3
4
5
graph LR;
取指令 --> 指令译码;
指令译码-->指令执行;
指令执行-->存储访问;
存储访问-->写回;

取指令:Instruction Fetch,从存储器取指令到CPU

指令译码:Instruction Decode,对取回的指令进行拆分和解释,识别和区分出不同的指令类别及各种获取操作数的方法

指令执行:Instruction Execute,使用硬件功能单元执行指令,最常见功能单元为算术逻辑部件运算器(Arithmetic Logical Unit,ALU)

存储访问:Memory Access,根据指令需要,有可能要访问主存,读取操作数,具体见下表

方式 算法 优点 缺点
隐含寻址 默认操作数地址 不访存 数据范围受限
立即寻址 D = A 不访存 操作数值范围受限
直接寻址 EA = A 简单 地址范围受限
间接寻址 EA = (A) 地址范围大 多次访存
寄存器寻址 EA = R 不访存 地址范围受限
寄存器间接寻址 EA = ® 地址范围大 访存
偏移寻址 EA = A + ® 灵活 复杂
段寻址 EA = A + ® 灵活 复杂
堆栈寻址 EA = SP 不访存 应用受限

写回:把执行指令阶段的运行结果数据“写回”到某种存储形式,经常是写到cpu内部寄存器以便下次快速使用

流水线

若处理器无流水线结构,一条指令执行一般需要五个处理器周期;流水线使用锁存器(latch,用来缓存电信号)让不同指令的各步操作重叠,从而实现多条指令在不同周期并行处理,只执行一条指令的话,流水线不会提高效率。

分支预测

流水线架构对顺序执行的命令,性能提升明显,但遇到命令跳转(goto系列等)就会性能降低,那么就出现了分支预测期,提前把预测到的指令存入流水线,分支跳转指令完成后如果预测正确,流水线正常运行,若错误,清空流水线然后执行正确的指令

乱序执行

打乱程序原本的执行顺序(类似上层使用异步,编译器也会乱序执行)

cpu的乱序执行一般都使用Tomasulo算法,包括

  • Common Data Bus (CDB).
  • Unified Reservation Station (Scheduler).
  • Register Renaming (Reorder Buffer).

该算法虽然是乱序执行, 但是会顺序完成 (retire), 只有在retire后它的输出才会architectually visible (简单地说, 不影响程序逻辑), 但是没有architectually visible不等于没有影响, 当输出更新到reservation station后, 因为cdb的存在, 其他指令已经可以读到. 另外, 非常重要的一点, 异常只有在指令retire的时候才会触发, 对于上面的例子, 即使cpu已经检查到第一条指令没有访问权限, 也只能等到该指令retire时才会触发, 取决于该指令在ROB的位置, 可能马上触发也可能很久之后, ROB容量可以很容易做到比如192这个级别.

熔断漏洞(利用乱序执行)

cpu在执行A语句的同时将B语句中的内存位置的信息加载到cache中,这个加载的过程忽略了权限的判断之后再执行B、C语句,在执行B语句时发现并没有权限,所以放弃乱序执行的结果,回滚到最初的状态依次执行。此时cache中的信息没有还原。之后通过边信道攻击来测试数据,发现对于某一个数据的访问要远远快于其他数据的访问,那么就可推断数据在cache中,并且可以反推回它的内存地址。

幽灵漏洞(利用分支预测)

和熔断差不多,比如if else 中,提前预测某一条,预测错误,状态回滚,边信道攻击,反推内存地址

解决办法

打补丁,关闭乱序执行、分支预测,不过个人电脑建议别关,关了会影响性能。