LWN:每次系统调用都随机修改内核堆栈位置!

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

Per-system-call kernel-stack offset randomization

By  Jonathan Corbet

March 27, 2020

原文来自:https://lwn.net/Articles/816085/

主译:https://www.deepl.com/translator

近年来,内核(终于)在安全加固方面有了更多进步,可以说kernel已经 "很难 "被攻破了。不过,攻击者仍能找到利用内核漏洞的方法。有一个信息可以对攻击者非常有帮助,那就是内核堆栈的位置;Kees Cook和Elena Reshetova的这组patch set可能很快就会让这些信息变得更难获得,而且就算拿到了stack地址也无法利用了。

内核堆栈一直是一个有吸引力的目标。它通常包含着无数的有用信息。比如可以用来查找其他内核数据结构的位置。如果它可以被写入,那么它可以被用来进行Return Oriented programming(面向返回编程)攻击。在现实中看到的许多攻击(Cook提到的这个利用video4linux的攻击就是一个例子:https://a13xp0p0v.github.io/2020/02/15/CVE-2019-18683.html  )都首先要能确定内核堆栈位置,作为接管这个正在运行的系统的一个前提步骤。

在当前的内核中,内核堆栈是在进程创建时从vmalloc()区域分配的。这种方法就使得各个进程的内核堆栈的位置都很难猜测,因为它取决于创建时内存分配器的状态。但是,一旦栈被分配了,它的位置在进程运行的过程中一直保持固定。因此,如果攻击者能够猜出目标进程的内核堆栈在哪里,那么只要该进程还在运行,这个位置信息就一直有效。

事实证明,攻击者有很多方法可以做到这一点。尽管已经进行了大量清理,但仍有一些内核消息会在kernel message中暴露数据结构的地址,也包括堆栈地址。还有一些利用了ptrace()或cache timing的攻击方式,也可以用来确定堆栈位置。因此,尽管堆栈位置是动态分配的,但是它并不能完全阻止攻击者找到这个信息。

Cook和Reshetova的patch set(灵感来自于PaX RANDKSTACK功能,尽管实现方式不同)通过改变进程每次进行系统调用时的内核堆栈偏移来解决这个问题。具体来说,它修改了系统调用的入口代码,从而会让下面的行为依次发生:

  • 包含了处理器寄存器状态的pt_regs结构被推送到stack之内,这一点跟当前kernel行为没有变化。

  • 调用 alloca(),使用一个随机值参数。这是在stack上 "分配 "一块随机大小的内存,实际只是根据这个数值将堆栈指针向下移动这么多距离。

  • 系统调用继续进行,它使用的堆栈指针就是在目前这个随机变动过的位置了。

换句话说,内核堆栈本身并没有移动,但实际的堆栈内容会跳转一段偏移量,每次系统调用时堆栈位置都不一样。这使得任何依赖于堆栈中特定位置的 数据进行的 攻击很可能会失败;即使攻击者成功地弄清楚了堆栈的位置,他们也不知道某次系统系统调用时此数据位于堆栈中的确切位置。

必须在对堆栈进行随机化之前就将pt_regs结构压入堆栈。上面提到的ptrace()攻击可以用来定位这个结构(从而找到内核堆栈);如果在将堆栈进行偏移之后再保存pt_regs结构,那此类攻击就可以获取到这个关键的偏移量信息。

目前,这个随机偏移量是通过读取CPU的time-stamp计数器中的一些低阶bit来获得的。Cook指出,未来还可以增加其他更强大随机熵来增强随机性,但他认为目前的补丁可以先合入合入,今后再继续改善这一点。目前在64位系统上有5位bit作为熵来确定堆栈偏移量,32位系统上用了有6位bit。这个随机数范围并不是很大,但已经足以让任何依赖于精确的内核堆栈位置的攻击,在最初的几次尝试中都会失败,并产生kernel oops。当然完全可以继续增大熵,但代价是浪费更多的堆栈空间。

在使用此功能的情况下,Cook使用no-op(什么都不做)的系统调用来测了一下性能,看到有0.9%的额外性能损耗。在那些会做具体操作的系统调用场景下,这个开销占比当然会更少。但对于那些连这一点代价都不想付出的人来说,有一个静态编译选项可以关闭此随机化功能。

最终,我们利用了这么一个相对简单的机制,进一步加固了内核。Cook指出这个方案并不完美,他补充说:" most things can't be given the existing kernel design trade-offs. " 如果其他开发者也同意的话,这个针对各个系统调用随机进行堆栈偏移的方案很可能会作为又一个加固技巧来合入mainline kernel。

全文完

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

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

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

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章