难以想象的芯片UAF漏洞,Zenbleed漏洞分析

难以想象的芯片UAF漏洞,Zenbleed漏洞分析

原创 张一白 华为安全应急响应中心 2023-11-24 18:10

1

简介

Zenbleed
是一个在
AMD Zen2
架构上的指令集漏洞,这个漏洞也是由预测执行产生的。但相对于
Spectre
漏洞,
Zenbleed
并不需要时间侧信道,攻击方法也远比
Spectre
简单。这个漏洞更类似于常规程序中由
malloc/free
导致的
UAF
问题。

2

了解
x86 simd
指令

随着对
CPU
计算性能需求的增长,
x86
处理器引入了
 MMX,SSE,AVX 

SIMD
指令,也加入了用于这些指令的专用寄存器
 MM

XMM

YMM

ZMM
。在
Zen2
架构中,对这类指令最高支持到
AVX2
,寄存器最大是
256bit

YMM
系列寄存器。

这里要注意,
MM

XMM

YMM
的关系就像
 ax

eax

rax
一样,
MM0

XMM0

YMM0

64bit
低位,
XMM0

YMM0

128bit
低位,它们并不是独立的寄存器。

在程序中,这些寄存器不仅是用来进行数据计算,也用于加速诸如
strcmp, memcpy, strlen
等标准库函数。

比如在
glibc
中,就有如下使用
AVX2
指令优化的
strcmp

(gdb) x/20i __strlen_avx2...   <__strlen_avx2+9>:   vpxor  xmm0,xmm0,xmm0...   <__strlen_avx2+29>:  vpcmpeqb ymm1,ymm0,YMMWORD PTR [rdi]   <__strlen_avx2+33>:  vpmovmskb eax,ymm1...   <__strlen_avx2+41>:  tzcnt  eax,eax   <__strlen_avx2+45>:  vzeroupper   <__strlen_avx2+48>:  ret

第一段vpxor xmm0,xmm0,xmm0
将清空整个
ymm0
寄存器
(
写入
XMM
寄存器将自动清空
YMM
的高位
)

图片来源:
https://lock.cmpxchg8b.com/zenbleed.html

第二段vpcmpeqb ymm1, ymm0, [rdi]

rdi
指向的内存
32
字节与
YMM0
比较,比较的结果存入
YMM1
中。相同的字节会被设置成
0xFF
,不同的字节会被设置成
0x00

图片来源:
https://lock.cmpxchg8b.com/zenbleed.html

随后vpmovmskb eax, ymm1

ymm1
中保存的结果转存到
eax
中,
ymm1
中每一个不为
0x0
的字节将设置
eax
对应的比特位为
1

图片来源:
https://lock.cmpxchg8b.com/zenbleed.html

最后判断字符串的长度,我们就只需要数出来
eax
中有多少个前导为
0

bit
。tzcnt eax, eax
就正好是做这个的。

图片来源:
https://lock.cmpxchg8b.com/zenbleed.html

这段代码还执行了vzeroupper
,用于清空所有
YMM
寄存器的高
128bit
,同时也可以避免在从
VEX
模式切换到
non-VEX
模式带来的性能损失。因此,他出现在了这段代码的末尾。

3

问题所在

我们看到上面有多个清空
YMM

128
位的操作,但
CPU
是怎么完成这个操作的呢?


CPU
中,每个寄存器并非一个独立的存储空间,而是利用
寄存器分配表(Register Allocation Table


寄存器文件(Register File
。寄存器文件类似于一个数组,每一个元素存储着一个寄存器的值,而寄存器分配表会存储寄存器名称和寄存器文件数组下标的关系。

当我们清空某个寄存器时,
CPU
并不会去清空寄存器文件中实际存储的值,而是设置寄存器分配表中的
z-bit,
或者说将寄存器分配表标记为未分配。这个
flag
可以独立地被设置于
YMM
的高
128
位和低
128
位(也就是
XMM
)。所以在vzeroupper
执行时,
CPU
会释放寄存器文件中对应的表项,并将寄存器分配表对应项设置为
0

图片来源:
https://lock.cmpxchg8b.com/zenbleed.html

但是,为了充分利用流水线,我们的
CPU
现在都有一个叫
投机(预测)执行

的功能。如果
CPU
投机执行了vzeroupper
,但是后续发现预测错误,这时候该怎么办呢?最简单的办法就是直接将设置的
z-bit
去掉,让寄存器分配表表项重新映射到原来的寄存器文件表项上。

But wait
…如果这时候另一个
CPU
核已经占用了这个表项
那会怎么样呢?
?

图片来源:
https://lock.cmpxchg8b.com/zenbleed.html

UAF triggered!

4

漏洞

部分
AMD Zen2 CPU
在从错误投机的vzeroupper
指令回滚状态时,可能会出现上述的错误。受影响的至少包括以下产品
:
–     
AMD
Ryzen 3000 Series Processors

  • AM
    D
    Ryzen PRO 3000 Series Processors

  • AMD
    Ryzen Threadripper 3000 Series Processors

  • AMD
    Ryzen 4000 Series Processors with Radeon Graphics

  • AMD
    Ryzen PRO 4000 Series Processors

  • AMD
    Ryzen 5000 Series Processors with Radeon Graphics

  • AMD
    Ryzen 7020 Series Processors with Radeon Graphics

  • AMD
    EPYC

    Rome

    Processors

首先我们需要触发
XMM寄存器合并优化(XMM Register Merge Optimization

然后再来个寄存器重命名,最后再整个错误预测的vzeroupper
。只要精细的控制时间窗就能触发这个漏洞。

由于一些基础的操作,比如
strlen

memcpy

strcpy
都使用了这类
simd
寄存器进行性能优化,所以我们可以利用这个漏洞有效的监控系统中发生的这些行为,而且无论是发生在虚拟机、沙箱、容器、进程中。

因为同一个寄存器文件是被同一个物理核中的所有寄存器共享的,甚至两个超线程核都是共享的同一个寄存器文件。

5

复现

复现这个问题的方式有很多,我们可以看一个很简单的例子
:

    vcvtsi2s{s,d}   xmm, xmm, r64
    vmovdqa         ymm, ymm
    jcc             overzero
    vzeroupper
overzero:
    nop

cvtsi2sd
是用来触发寄存器合并优化的,它实际做了啥并不重要,任何可以触发寄存器合并优化指令都可以。然后我们用
vmovdq
触发寄存器重命名,然后用一个条件跳转让
cpu
预测错误,投机执行vzeroupper
但随后回滚操作,就可以触发这个问题了。

触发后,我们就能直接从
ymm
寄存器中,读出别的程序可能正在处理的数据。

实际的
复现
比这个复杂一些,可以后台索要附件查看。最终,原作者实现了可以泄露
30kb
每核每秒的能力,这个速度足以监控一些密钥和密码信息。

6

修复

AMD
已经提交了最新的微码,
linux
用户更新
linux-firmware
即可。你的主板厂家也应该会放出含有最新微码的
BIOS/UEFI
,请及时更新。

如果暂时无法更新,可以修改DE_CFG[9]
来规避,在
linux
上,使用以下命令即可。

# wrmsr -a 0xc0011029 $(($(rdmsr -c 0xc0011029) | (1<<9)))

但这个会带来性能损失。

7

检测

没有什么好的办法检测和识别此类攻击的存在,因为它不需要任何的权限或特殊系统调用。当然我们也绝对不能通过检查vzeroupper
的调用来判断,它的使用实在是太广泛了。

8

结论

内存管理在哪儿都很难,即使是在芯片中。

9

参考阅读

寄存器文件:
https://zh.wikipedia.org/wiki/
寄存器堆

寄存器重命名:
https://zh.wikipedia.org/wiki/
寄存器重命名

XMM
寄存器合并优化:
https://www.amd.com/en/server-docs/software-optimization-guide-for-amd-epyc-7003-processors-zip-format ,
section 2.11.5

备注:

本文绝大多数内容翻译自漏洞发现者的博客原文,本人翻译能力有限,读者感兴趣的话阅读原文可获得更清晰的理解。https://lock.cmpxchg8b.com/zenbleed.html


推荐阅读

华为终端安全奖励计划|漏洞奖金翻倍活动强势回归–更高奖金,更多守护

“最新奖励计划”正式发布!!

关于CVSS V4.0,你想知道的都在这了!

点这里
关注我们,一键三连~