为了证实Spectre漏洞对于龙芯3A的影响,我对 https://github.com/Eugnis/spectre-attack 这个PoC进行了MIPS下的移植。
因为我并不完全理解这个漏洞的工作原理,我仅仅是把其中X86相关的指令用我认为类似的MIPS架构下的类似指令实现,大致的替代方案是 rdtsc(p)使用MIPS下的dmfc0将 Coprosser 0中的9号Count寄存器拷贝到通用寄存器来读取指令Count(dmfc0 %0, $9)(精确到两个时钟周期,相比rdtsc的一个周期还是有所不足,不过这已经是MIPS下精度最高的时钟寄存器了。) 而cflush缓存刷新指令,则通过SYSMIPS这个System Call(系统调用)下的 FLUSH_CACHE 指令来进行(syscall(sysmips, FLUSH_CACHE, NULL, NULL);),这个指令是用户态下唯二的可以刷新缓存的指令。但是相较cflush而言的不足是cflush可以清除指定线性地址的缓存,而这个syscall只能清除全局缓存。另一个cacheflush指令 看似可以刷新指定线性地址缓存,而仔细读了读内核代码发现虽然Linux-MIPS Wiki上有记载(https://www.linux-mips.org/wiki/Cacheflush_Syscall ),但并没有在内核中实现。 我在龙芯云平台3A2000的Docker中编译运行,接近两个小时都没有利用成功。
关于失败的原因,可能是因为我这样粗暴的移植不行,也可能是是因为每次都刷新全局缓存效率太低,还有可能是龙芯CPU主频太低,或者其他因素。当然,我认为最好的情况就算龙芯处理器上根本不存在这个漏洞。如果我的移植可靠的话,那么即使存在,利用难度也会很大。