为了减少内核或跨进程内存泄漏(Spectre攻击),Linux内核1将使用一个新选项编译,-mindirect-branch=thunk-extern
引入到gcc
,以便通过所谓的retpoline执行间接调用。
这似乎是一个新发明的术语,因为谷歌搜索只是最近才使用(通常都是在2018年)。
1但是,它不是Linux特有的--类似或相同的构造似乎被用作其他操作系统缓解策略的一部分。
sgbj在谷歌的保罗·特纳撰写的评论中提到的文章更详细地解释了以下内容,但我还是试试看:
根据目前有限的信息,我可以把它拼凑在一起,一个retpoline是一个返回蹦床,它使用一个从不执行的无限循环来防止CPU推测间接跳转的目标。
基本方法可以在Andi Kleen的内核分支中看到:
.macro NOSPEC_CALL target
jmp 1221f /* jumps to the end of the macro */
1222:
push \target /* pushes ADDR to the stack */
jmp __x86.indirect_thunk /* executes the indirect jump */
1221:
call 1222b /* pushes the return address to the stack */
.endm
call retpoline_call_target
2:
lfence /* stop speculation */
jmp 2b
retpoline_call_target:
lea 8(%rsp), %rsp
ret
这里的控制流可能会有点混乱,所以让我澄清一下:
调用
将当前指令指针(标签2)推送到堆栈。lea
将8添加到堆栈指针,实际上丢弃了最近推送的四字,这是最后一个返回地址(标签2)。之后,堆栈的顶部再次指向真实的返回地址ADDR。ret
跳转到*addr
并将堆栈指针重置到调用堆栈的开头。最后,整个行为实际上等同于直接跳转到*addr
。我们得到的一个好处是,在执行call
指令时,用于返回语句(返回堆栈缓冲区,RSB)的分支预测器假定相应的ret
语句将跳转到标签2。
但是请注意,规范中从未提到LFENCE和PAUSE会导致管道停顿,所以我在这里读了一些字里行间的内容。
现在回到您最初的问题:内核内存信息公开是可能的,因为两个想法的结合:
>
即使当推测错误时推测执行应该没有副作用,推测执行仍然会影响缓存层次结构。这意味着当推测性地执行内存加载时,它可能仍然导致缓存行被逐出。通过仔细测量映射到同一缓存集上的内存的访问时间,可以识别html" target="_blank">缓存层次结构中的这种变化。
当内存读取的源地址本身是从内核内存读取时,您甚至可以泄漏任意内存的一些位。
Retpoline作为一种缓解策略,将间接分支交换为返回,以避免使用来自BTB的预测,因为它们可能会被攻击者毒害。Skylake+的问题是RSB下溢回到使用BTB预测,这允许攻击者控制猜测。
我刚刚开始在Haskell中编程,我遇到了以下定义:
伙计们,最近我决定回到PHP,做一些比简单的登录页面更复杂的事情。3年来,我一直在Java /JavaEE编程,对Java应用程序的体系结构有很好的理解。基本上,一个虚拟机(一个简单的操作系统进程)运行被称为字节码的编译代码。一个简单的Javaweb服务器基本上是一个java应用程序,它监听提供给Http请求的TCP端口,并相应地做出响应,当然它更复杂但这是它最初的工作。 现在,PHP怎么样?它是
我搜索过,似乎这被称为列表理解,但它是如何工作的?
问题内容: 我不明白杰克逊的@JsonView( Views.MyClass.class )是什么。我知道我可以用这种方式注释POJO的字段和方法, 以过滤未 注释的字段和方法,以免它们被JSON序列化。但是,什么是Views.Myclass类?它是Jackson库的模板类吗? 为什么在Views类中可以有很多类?例如这样: 为什么需要它,它如何工作? 问题答案: 用于根据序列化的上下文过滤字段。
AAPT(安卓资产打包工具)是什么意思?它是如何工作的? 我可以使用AAPT将一个应用程序的文件发送到另一个应用程序的APK文件中吗?
问题内容: 我不太了解其工作原理和作用。 我的主要目标是将它与配合使用以提高精度。 问题答案: 使用要跟踪字符串和重复值 通常按项目本身跟踪每个项目。对于给定的阵列,试图跟踪由每个变化的。问题是我们有重复的值,而角度将引发错误。解决该问题的一种方法是通过其他方式对对象进行角度跟踪。对于字符串,这是一个很好的解决方案,因为您实际上没有其他跟踪字符串的方法。 并触发摘要和输入焦点 您暗示您对角度有些陌