在查看这篇zenbleed文章时,发现随机生成的指令序列和相同的序列但添加了随机对齐、序列化和推测栅栏产生了不匹配的最终状态。
例如
Original Code Fuzzed Code
-------------------- --------------------
movnti [rbp+0x0],ebx movnti [rbp+0x0],ebx
sfence
rcr dh,1 rcr dh,1
lfence
sub r10, rax sub r10, rax
mfence
rol rbx, cl rol rbx, cl
nop
xor edi,[rbp-0x57] xor edi,[rbp-0x57]
在那篇文章中提到它可能表明存在错误
如果最终状态不匹配,那么一定存在一些错误 它们是如何在微架构上执行的——这可能表明 一个错误。
注释
作为开发人员,我们监控宏观架构状态,这只是 诸如寄存器值之类的东西。还有微架构 我们几乎看不到的状态,比如分支预测器, 无序执行状态和指令管道。
问题
微架构执行时有没有什么情况不是bug?
当执行微架构时
这句话没有道理。每个指令序列都必须由微架构(CPU 硬件设计)执行。 CPU 硬件没有任何其他方式来运行机器代码。
任何可观察到的(体系结构,而不是计时)结果始终需要与按程序顺序一次执行一个结果(从其他线程观察到的内存内容除外)相匹配。即乱序执行必须保留串行执行模型的错觉。
由于
lfence
、mfence
、nop
等对架构状态(寄存器/内存内容)没有影响,因此它们不应该改变任何内容对于单线程代码。 如果它们确实造成了差异,那始终是一个问题。我认为这就是你想问的,这就是引文所说的。
有诸如
rdtsc
和 rdpmc
之类的指令可以读取时间戳或性能计数器;当您将慢速指令 (TSC) 或额外的指令/微指令放入序列中时,这些当然会给出不同的结果。 rdpmc
本质上是将微架构计数器读入架构状态(寄存器值),而rdtsc
是读取时间,因此从来没有期望它们会在有或没有序列化的情况下给出相同的结果。