Open v4if opened 6 years ago
熔断和幽灵
对于Meltdown原因是在Intel 的投机执行Speculative execution,即乱序处理器会在某个指令在等待的时候,预先开始执行之后的指令,然后通过speculation的机制来保证如果预先执行了不该执行的指令,不会产生体系结构层面可见的结果,把执行结果discard掉,但是不会flush更新的缓存,而且在投机执行的时候Intel的CPU没有进行权限判断,为了提高执行效率,而是选择在commit的时候进行页表访存地址需要的权限进行检查,对权限不足的结果discard掉,因此即使在commit的时候由于访存权限被discard掉,仍然会留下缓存更新的痕迹
time based attack:时间旁路攻击,即数据被缓存之后的访问时间与直接从内存load的时间差异大,可以通过访问时间判断该page是否被缓存
现代OS虚拟内存在设计的时候应用程序和内核空间在同一虚拟地址空间,一般将3G以上内核虚拟空间直接线性映射到物理内存空间,为了缓解内核漏洞利用出现了KALSR内核地址随机化机制,但还是共享同一虚拟地址空间,应用程序对内核空间访问的限制是硬件根据页表访存地址权限进行禁止
到这里可能会有疑问,只是执行了不该执行的指令,并且对结果已经discard掉了,会产生什么影响。
这里还有一个预执行产生的后果没有消除掉,那就是预执行过程中对缓存的更新,而且前面说了一个前提条件,也就是Intel的芯片为了更多的预支处理器的性能,在对后续指令进行投机执行的时候没有进行权限检查!
也就是说低权限级别即用户程序可以在投机执行的时候对内核的虚拟地址进行访存!但是访存之后怎么把结果带出来,在commit的时候会对权限进行检查,如果不符合就会抛异常,然后把结果discard掉,这里巧妙的利用了不会flush掉的缓存信息然后进行time based attack旁路攻击。
用户态程序可以开辟一段256个page大小的内存,用来做probe array探测数组,并且保证没被cache过。假设我们要读取kernel_vm_addr中的内容,可以先读取kernel_vm_addr的第一个byte,这条指令肯定会产生异常,但是由于投机执行,后面的指令仍会执行,把读到的第一个byte_data 4096作为索引去访问probe array,即probe_array[byte_data 4096],这会导致该地址的页块被cache住,而且访存指令异常后不会flush掉,因此可以通过测量对256个page的内存访问时间得到第一个byte的数据内容,以此类推。
给出的应对方案是KPTI/KAISER:把内核从程序的虚拟地址空间里移出去,只保留最最最基本的东西,需要用的时候再切换回来,在切换的时候会造成TLB的刷新
参考的地方: bnm zasdfg - 如何看待 2018 年 1 月 2 日爆出的 Intel CPU 设计漏洞 某琳 - 如何看待 2018 年 1 月 2 日爆出的 Intel CPU 设计漏洞
熔断和幽灵
对于Meltdown原因是在Intel 的投机执行Speculative execution,即乱序处理器会在某个指令在等待的时候,预先开始执行之后的指令,然后通过speculation的机制来保证如果预先执行了不该执行的指令,不会产生体系结构层面可见的结果,把执行结果discard掉,但是不会flush更新的缓存,而且在投机执行的时候Intel的CPU没有进行权限判断,为了提高执行效率,而是选择在commit的时候进行页表访存地址需要的权限进行检查,对权限不足的结果discard掉,因此即使在commit的时候由于访存权限被discard掉,仍然会留下缓存更新的痕迹
time based attack:时间旁路攻击,即数据被缓存之后的访问时间与直接从内存load的时间差异大,可以通过访问时间判断该page是否被缓存
现代OS虚拟内存在设计的时候应用程序和内核空间在同一虚拟地址空间,一般将3G以上内核虚拟空间直接线性映射到物理内存空间,为了缓解内核漏洞利用出现了KALSR内核地址随机化机制,但还是共享同一虚拟地址空间,应用程序对内核空间访问的限制是硬件根据页表访存地址权限进行禁止
到这里可能会有疑问,只是执行了不该执行的指令,并且对结果已经discard掉了,会产生什么影响。
这里还有一个预执行产生的后果没有消除掉,那就是预执行过程中对缓存的更新,而且前面说了一个前提条件,也就是Intel的芯片为了更多的预支处理器的性能,在对后续指令进行投机执行的时候没有进行权限检查!
也就是说低权限级别即用户程序可以在投机执行的时候对内核的虚拟地址进行访存!但是访存之后怎么把结果带出来,在commit的时候会对权限进行检查,如果不符合就会抛异常,然后把结果discard掉,这里巧妙的利用了不会flush掉的缓存信息然后进行time based attack旁路攻击。
用户态程序可以开辟一段256个page大小的内存,用来做probe array探测数组,并且保证没被cache过。假设我们要读取kernel_vm_addr中的内容,可以先读取kernel_vm_addr的第一个byte,这条指令肯定会产生异常,但是由于投机执行,后面的指令仍会执行,把读到的第一个byte_data 4096作为索引去访问probe array,即probe_array[byte_data 4096],这会导致该地址的页块被cache住,而且访存指令异常后不会flush掉,因此可以通过测量对256个page的内存访问时间得到第一个byte的数据内容,以此类推。
给出的应对方案是KPTI/KAISER:把内核从程序的虚拟地址空间里移出去,只保留最最最基本的东西,需要用的时候再切换回来,在切换的时候会造成TLB的刷新
参考的地方: bnm zasdfg - 如何看待 2018 年 1 月 2 日爆出的 Intel CPU 设计漏洞 某琳 - 如何看待 2018 年 1 月 2 日爆出的 Intel CPU 设计漏洞