## Spectre > 根源在于CPU的『推测执行』。 场景: ``` if (a =1 ){ a1(); } else { b(); } ``` 原本,对于各个进程来说,某个进程是无法访问其他进程的内存的。 CPU速度太快,RAM跟不上CPU的节奏。CPU在碰到分支语句需要进行条件判断的时候,CPU等不及要执行下去了(不执行的话就只能休息,浪费了CPU的运算能力)会先执行各个分支的指令(推测执行。根据以往的经验推测哪个分支的条件最有可能满足。然而黑客可以利用这一点来构造一个特殊的条件分支来误导CPU进行错误的判断)。推测执行之后,等待条件判断结果,要么取这个结果,要么丢弃这个结果。反正就是稍微费一些电嘛,不过从长远来看这种方法相对于单线程的执行方式来说还是效率更高的。然后将各个分支的指令的计算结果存储在cache上。如果最终判断出来分支条件,实际会进入某一个分支,于是CPU就会把这个正确的分支下的执行结果返回,而其他分支的执行结果丢弃。但是其实这些内容都在CPU的cache中。本身这个CPU的cache对于其他进程也是无法访问的,但是其他进程可以旁敲侧击来推断其内容。怎么个旁敲侧击法呢? 就是通过跑字典,然后测试返回结果的时延。如果命中了cache,时延会远低于没有命中cache的情况。 ``` t = a+b u = t+c v = u+d if v: w = e+f x = w+g y = x+h ``` 这段代码,如果v为0,则会耗费4个CPU时钟周期;若v不为0,则耗费7个时钟周期。 而如果分支预测器可以『预测』if条件成立,那么就会变成这样: ``` t = a+b u = t+c v = u+d w_ = e+f x_ = w_+g y_ = x_+h if v: w, x, y = w_, x_, y_ ``` 然后又可以变成这样的并行执行方式: ``` t, w_ = a+b, e+f u, x_ = t+c, w_+g v, y_ = u+d, x_+h if v: w, x, y = w_, x_, y_ ``` 就只用3个时钟周期了。 根源就是CPU太快,内存跟不上,为了提高效率,CPU想办法不得不『推测执行』 ## 什么是cache 就是CPU的片上存储空间。对于最近从内存中载入数据(以及其相邻地址数据)的一种缓存。 cache有什么用呢? 比如这两行代码: ``` a = mem[0] b = mem[1] ``` 本身执行每行只要0.5ns;而为了取mem[0]这个数据,需要从内存中去读(在没有cache的情况下),需要100ns。 而有了cache的话,就变成这样: ``` a = mem[0] # 100ns delay, copies mem[0:15] into cache b = mem[1] # mem[1] is in the cache ``` 大概是100ns的时间多一点。(因为执行第二行时mem[1]已经在取mem[0]的过程中把[0:15]都拿过来放到cache中了)。 于是从Spectre和Meldown攻击的角度来看,只需要计算某个数据(地址)的读取时间,就可以判断这个数据(地址)是否在cache中了。 参考: https://www./watch?v=tdmGFiILNcY https://www./watch?v=q3-xCvzBjGs https://www./blog/why-raspberry-pi-isnt-vulnerable-to-spectre-or-meltdown/ ## Meltdown > 根源在于CPU的『乱序执行』 场景: ``` a = 1+2; b = 7*8; ``` 参考:https://www./watch?v=JSqDqNysycQ |
|
来自: 昵称54185769 > 《待分类》