关注了就能看到更多这么棒的文章哦~

Stuffing the return stack buffer

By Jonathan Corbet
July 22, 2022
DeepL assisted translation
https://lwn.net/Articles/901834/

"Retbleed" 系列漏洞,是一类牵涉到 return 指令的投机执行(speculative-execution)漏洞。针对 Retbleed 的加固措施已经在 mainline kernel 中了。但是,截至本文写作时,还有一些剩余问题导致无法进入 stable update 发布版。防护 Retbleed 的问题会严重影响性能,尤其是在一些英特尔处理器上。Thomas Gleixner 和 Peter Zijlstra 认为他们已经找到了一个更好的方案,不需要使用现有的防护措施,而是对处理器的预测执行机制进行误导来解决这个问题。

如果 CPU 要对 return 指令进行推测执行,那么就必须对代码将返回的位置有一定的了解。在最近的英特尔处理器中,有一个特殊的隐藏数据结构,称为 "返回堆栈缓冲区"(RSB, return stack buffer),用于缓存存放预测的返回地址。RSB 可以容纳 16 个条目,因此,如果一个调用链的深度超过这个数字的话,它就必须得放弃掉最早的那个 entry。这样在这个非常深的调用栈在返回时,RSB 可能会出现 underflow (也就是想要的数据在这里并不存在了)。人们可能认为这时 speculation 预测会在此时停止,但恰恰相反,CPU 会求助于其他的一些启发式方法,比如依赖 branch history buffer 来预测。唉,现在人们已经充分认识到可以通过精心构造特殊的 branch history buffer 来进行攻击了。

因此,内核中的这种非常深的调用关系就很容易受到预测执行攻击。在从 Skylake 一代开始的英特尔处理器上,防止这种攻击的唯一方法就是打开 CPU 中 indirect branch restricted speculation(IBRS) CPU 这个 "feature",这是由英特尔在 Spectre 时代的早期添加的功能。IBRS 确实有效,但它有一个不受欢迎的副作用,即性能降低 30%。用户自然对这种解决方案缺乏热情。

Another way

Gleixner 和 Zijlstra 决定尝试一种新方法。在这些处理器上只有在 RSB underflow 的情况下才能利用预测执行来控制 return call。因此,如果可以阻止 RSB underflow,那么这个特殊的问题就会消失。而我们似乎可以通过在 RSB 有可能耗尽条目时来 "stuffing (填充内容)" 从而实现这个效果。

这就马上引出了两个新的挑战:需要知道 RSB 何时处于快要 underflow 的情况,以及找到一种方法来填充内容。第一个问题,是通过跟踪当前的调用链深度来处理的,采用的是一种近似方式。构建系统会被修改为在内核镜像的可执行文件中创建几个新的 section,来存放内核函数的 entry 和 exit 位置会执行的小段代码,用来进行跟踪。当 RSB stuffing 功能启用时,函数 entry 增加的额外代码就会在每次进入各个函数时被调用,exit 的额外代码将在离开函数执行。

RSB 的状态会被跟踪下来,有一个 per-CPU 的 64 位值,初始化为:

0x8000 0000 0000 0000

函数 entry 的额外代码会通过将其右移 5 位来变相 "增加" 这个计数器。处理器会对这个值进行符号扩展,因此,在第一次调用后,该计数器将看起来是这样:

0xfc00 0000 0000 0000

如果再连续发生 12 次调用的话,这个符号位将一直向右扩展,计数器中的最高位的 1 就会一直传递到最右端;因此这个计数器无法可靠地统计超过 12 的数。这样一来,它就模仿了 RSB,其无法容纳超过 16 个 entry,这里留有四个调用来作为安全屏障;开发者使用移位来实现这一行为,就不需要引入 branch 了。每当函数返回时,就会发生相反的情况:计数器被左移 5 位。在 12 个 return 之后,再进行一次 shift 移位就会清除所有 bit,而计数器的值就变为了 0,这就提醒我们需要做一些事情来防止 RSB 用完了。

这时需要执行的工作,就是进行一系列非常快速短小的函数调用(是用汇编编码写的,在相关 patch 的末尾可以找到),于是增加了 16 个函数调用,从而也增加了 RSB 的内容。这些函数调用在返回时,都会立即执行一条 int3 指令;如果这些 return 调用都准备要做预测执行了,那么这个指令会阻止预测执行。当然,实际的内核并不想执行这些指令(或执行这么多 return 操作),所以用来填充 RSB 的代码里会增加了实际上的 stack pointer,来跳过这些填充进来的 call frame。

最终的结果是,RSB 不再符合实际的 call stack 了,其中充满了许多 entry,如果预测执行进去的话也不会有什么危害。在这个时候,call-depth 计数器就可以被设置为 -1(在 2 的补码中就是一个全 1 的数字),从而代表 RSB 已经填满了。内核现在就不怕 Retbleed 攻击了,要等到发生另一连串的 12 个 return 之后才会有问题,不过届时会做操作来把 RSB 再次填满。

Costs

我们做了大量的工作来减少这个方案的开销,特别是在不需要这个防护的系统上。编译出来的内核会像往常一样进行 direct call;在系统启动时如果选择 retbleed=stuff 了启动选项,那么所有这些函数调用都会被改为经过上面介绍的额外代码跳转来完成。这些 thunks 本身会被放置在一个 huge-page mapping 里面,从而减少对 TLB 的占用。即便如此,正如 patch 封面邮件中所说,这个方案还是有成本的。"我们都毫不意外地对这个结果恨之入骨"。

这些成本有几种体现形式。首先需要 "令人印象深刻 "的数量的内存得被用来保存这些额外的中转代码以及相关的处理工作。内核 size 增大,对其自身的性能也有影响,即使在没有启用 RSB stuffing 功能的系统上也会受到这个影响。额外的指令增加了 instruction cache 的压力,减缓了执行速度。信中说,最后一个问题可以通过在每个函数的开头来放置这些额外代码(而不是在一个单独的 section )来缓解。Gleixner 已经准备了一个 GCC patch 来实现这一目标,并且已经看到在使用这个 GCC patch 时,有一些性能损失就会被找回来。

邮件中包含了一长串的基准测试结果,比较了 RSB stuffing 与完全禁用缓解措施、以及使用 IBRS 的性能差异。RSB stuffing 的性能情况令人大开眼界,包括一个 microbenchmark 中测出了 382%的性能损失。不过,在所有情况下,RSB stuffing 都比 IBRS 表现得更好。

不过,只有在阻断 Retbleed 攻击的主要目标已经实现的情况下,还提供比 IBRS 更好的性能,这才有意义。邮件中这样说:

我们的假设是,在第 12 个返回点进行填充,足以在遇到 underflow 和并且转而求助于其他预测机制之前就破坏预测执行机制。测试下来可以证实是有作用的。Johannes [Wikner],retbleed 的研究人员之一,就试图对这种方法进行攻击,并且证实测试结果如水晶一般完美。

显然,没有什么科学证据能表明这可以经受住未来研究出的新的攻击,但我们现在能做的就是预测一下而已。

因此,RSB stuffing 似乎是有效的,至少目前看来是这样。这样一来,在需要防御 Retbleed 攻击的场景下,它是很有吸引力的。比如说在运行不受信任的用户的托管服务供应商都会需要这个。但没有人会对这里的额外开销感到满意,尽管它比 IBRS 好。对于很多用户来说,RSB stuffing 看起来是一个聪明巧妙的 hack 方案,并且值得庆幸的是他们并不需要真正使用这个功能。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

LWN:塞满return stack buffer!相关推荐

  1. C/C++轻松写可塞满硬盘的程序

    关于写可塞满硬盘的程序 我们先想想思路: 第一步:获取逻辑盘符 第二步:创建文件 第三步:文件写入数据 扩展要求: 一:隐藏窗口 二:文件设置为隐藏属性 下面我们对上述的思路介绍一个API,接受完后给 ...

  2. HTML5最新漏洞:用户硬盘或被垃圾数据塞满

    北京时间3月4日早间消息,HTML5编程语言的一个最新漏洞今天被发现,它允许网站利用数GB垃圾数据对用户展开轰炸,甚至会在短时间内将硬盘塞满.多款主流浏览器均会受此影响. 一位名叫菲罗斯·阿伯克哈迪杰 ...

  3. arXiv,30 岁生日快乐!它的诞生,始于一个​被塞满的邮箱

    来源丨新智元 arXiv 30岁啦! 这个收集物理学.数学.计算机科学.生物学与数理经济学的论文预印本的网站,始于1991年8月14日. 30年来,它见证了无数学者的耕耘. 根据Nature的报道,截 ...

  4. call stack and stack buffer overflow

    http://en.wikipedia.org/wiki/Call_stack http://en.wikipedia.org/wiki/Stack_buffer_overflow Stack_buf ...

  5. LWN:Fedora关于stack frame的争论!

    关注了就能看到更多这么棒的文章哦- Fedora's tempest in a stack frame By Jonathan Corbet January 16, 2023 DeepL assist ...

  6. 谷歌、哈佛联手绘出「百万分之一」人脑神经3D连接图!天量数据竟可塞满14亿块1T硬盘...

    来源:神经科技 编辑:Yezi 审阅:mingzlee7 前不久,谷歌和哈佛大学联手发布人脑神经3D连接图,涵盖人脑一百万分之一的信息,但数据已经塞满了1400块1T硬盘!现在,这个研究团队表示,这些 ...

  7. 测试环境服务器硬盘塞满问题排查

    项目中出现的问题 某天下午测试环境服务器出现tab无法补全命令,给出的提示大概意思就是说,无可用空间无法创建临时文件,不过这次跟上次出现的问题比较像,上次服务器出现的问题,因此楼主判断可能是服务器数据 ...

  8. 如何拯救容量已经快被塞满的SSD系统盘

    2019/01/08 如题,用SSD作为系统盘,其高性能对电脑提速巨大,我们习惯把软件都安装在系统盘,但是在对价格的妥协下,小容量的SSD会在日常的系统更新和缓存累积中显得非常拥挤. 以下为针对SSD ...

  9. 防止stack buffer overflows攻击的方法 : Canary 漏洞缓解机制

    快速链接: .

  10. 防止stack buffer overflows攻击的方法 : ShadowCallStack

    快速链接: .

最新文章

  1. 接口入参形式_某小公司RESTful、共用接口、前后端分离、接口约定的实践
  2. Python中的*args和**kwargs是什么?该如何使用?
  3. 新版 Edge 浏览器或将拥有两个不同的浏览器内核
  4. SPOJ - VLATTICE
  5. cvpr2018论文阅读
  6. LWIP裸机环境下实现TCP与UDP通讯(转)
  7. 秒杀场景_Sentinel在秒杀场景的应用_05
  8. 华为云设计语言_华为又一项黑科技即将来临:可即时翻译任何动物语言
  9. [React Native Android 安利系列]样式与布局的书写
  10. UNIX系统编程小结(三)----进程相关
  11. STM32CubeMX使用(七)之通用定时器和系统定时器
  12. 微星主板黑苹果_组装电脑哪个主板好?如何选择电脑主板?2020年电脑主板推荐及分析。...
  13. 如何更改字体隶书html,隶书转换
  14. 移动警务通GIS应用系统建设方案
  15. [硬件]超能课堂(181):我们为什么需要4+8pin CPU供电接口?
  16. 慧编程python硬件_什么是慧编程?慧编程介绍
  17. ip okhttp 设置_okhttp3及httpclient中的代理设置
  18. linux如何打开22端口?如何开启ssh远程链接
  19. DNS和HTTP服务
  20. CDR中实现浮雕效果的两种方法

热门文章

  1. 记一次笔记本电脑百度云盘无法连接网络问题
  2. windows10 DOS命令 小计
  3. oracle := 和=,oracle中 =: 和 := 分别是什么意思?
  4. 基于免费的SDCC开发51单片机
  5. 写口算用计算机作文600字,难忘的口算比赛作文600字
  6. Channel实现原理分析
  7. 1296. 划分数组为连续数字的集合
  8. NYOJ 找球号(二)(哈希表)
  9. Programming TCP/IP Windows Sockets in C++
  10. java对象转excel_【转】JAVA实现EXCEL的导入和导出(一)