gpt4 book ai didi

security - 什么是 retpoline,它是如何工作的?

转载 作者:行者123 更新时间:2023-12-02 13:58:43 24 4
gpt4 key购买 nike

为了缓解内核或跨进程内存泄露(Spectre 攻击),the Linux kernel1 will be compiled with a new option , -mindirect-branch=thunk-extern介绍给 gcc通过所谓的 retpoline 执行间接调用。

这似乎是一个新发明的术语,因为 Google 搜索只是最近才出现的(通常都在 2018 年)。

什么是 retpoline,它如何防止最近的内核信息泄露攻击?

1 然而,它不是 Linux 特有的——类似或相同的结构似乎被用作 mitigation strategies 的一部分。在其他操作系统上。

最佳答案

The article sgbj 在 Google 的 Paul Turner 撰写的评论中提到的更详细地解释了以下内容,但我会试一试:

据我目前有限的信息拼凑起来,retpoline 是 返回蹦床它使用永不执行的无限循环来防止 CPU 推测间接跳转的目标。

基本方法见Andi Kleen's kernel branch解决这个问题:

它介绍了新的 __x86.indirect_thunk 加载调用目标的调用,其内存地址(我将称之为 ADDR)存储在堆栈顶部,并使用 RET 执行跳转。操作说明。然后使用 NOSPEC_JMP/CALL 调用 thunk 本身。宏,用于替换许多(如果不是全部)间接调用和跳转。宏简单地将调用目标放在堆栈上,并在必要时正确设置返回地址(注意非线性控制流程):

.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的位置最后是必要的,以便当间接调用完成时,控制流继续使用 NOSPEC_CALL宏,所以它可以用来代替常规 call
thunk 本身如下所示:
    call retpoline_call_target
2:
lfence /* stop speculation */
jmp 2b
retpoline_call_target:
lea 8(%rsp), %rsp
ret

这里的控制流可能会有点困惑,所以让我澄清一下:
  • call将当前指令指针(标签 2)压入堆栈。
  • lea将 8 添加到堆栈指针,有效地丢弃最近推送的四字,这是最后一个返回地址(到标签 2)。此后,栈顶再次指向真正的返回地址ADDR。
  • ret跳转到 *ADDR并将堆栈指针重置为调用堆栈的开头。

  • 最后,这整个行为实际上等同于直接跳转到 *ADDR .我们得到的一个好处是,在执行 call 时,用于返回语句(返回堆栈缓冲区,RSB)的分支预测器指令,假设对应的 ret语句将跳转到标签 2。

    标签 2 之后的部分实际上永远不会被执行,它只是一个无限循环,理论上会用 JMP 填充指令管道。指示。通过使用 LFENCE , PAUSE或者更一般地说,导致指令流水线停顿的指令会阻止 CPU 在此推测性执行上浪费任何功率和时间。这是因为如果对 retpoline_call_target 的调用正常返回, LFENCE将是要执行的下一条指令。这也是分支预测器将根据原始返回地址(标签 2)预测的内容

    引用英特尔的架构手册:

    Instructions following an LFENCE may be fetched from memory before the LFENCE, but they will not execute until the LFENCE completes.



    但是请注意,规范从未提到 LFENCE 和 PAUSE 会导致管道停顿,所以我在这里阅读了一些内容。

    现在回到你原来的问题:
    内核内存信息泄露是可能的,因为两个想法的结合:
  • 即使当推测错误时推测执行应该是无副作用的,推测执行仍然影响缓存层次结构。这意味着当内存加载被推测执行时,它可能仍然导致缓存线被逐出。可以通过仔细测量映射到同一缓存集的内存的访问时间来识别缓存层次结构中的这种变化。
    当内存读取的源地址本身是从内核内存读取时,您甚至可以泄漏一些任意内存位。
  • Intel CPU 的间接分支预测器仅使用源指令的最低 12 位,因此很容易使用用户控制的内存地址毒害所有 2^12 条可能的预测历史。然后,当在内核中预测到间接跳转时,可以使用内核权限推测性地执行这些操作。使用缓存定时侧 channel ,您可以泄漏任意内核内存。

  • 更新:在 kernel mailing list 上,有一个持续的讨论让我相信 retpolines 并不能完全缓解分支预测问题,因为当返回堆栈缓冲区 (RSB) 运行为空时,更新的英特尔架构 (Skylake+) 回退到易受攻击的分支目标缓冲区( BTB):

    Retpoline as a mitigation strategy swaps indirect branches for returns, to avoid using predictions which come from the BTB, as they can be poisoned by an attacker. The problem with Skylake+ is that an RSB underflow falls back to using a BTB prediction, which allows the attacker to take control of speculation.

    关于security - 什么是 retpoline,它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48089426/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com