LWN:细粒度的KASLR(内核地址空间随机变化)!

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

Finer-grained kernel address-space layout randomization

By Jake Edge
February 19, 2020

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

先插个小调查,顺手点了吧,读者大人!

kernel address-space layout randomization (KASLR),会把kernel加载到一个随机的地址,它设计出来是为了让攻击者更加难于找到他们的目标代码或数据。不过它仅仅是给kernel text段加上了一个随机偏移量,这其实还是有弱点的,假如kernel里面某个东西的地址被攻击者获取到了,那么kernel里所有其他数据的位置都完全可以被算出来。最近新出了一个更细粒度的KASLR patch set,希望能通过在kernel启动的时候对各个函数进行重新排序,来弥补目前方案对kernel text p的保护缺陷。

Kristen Carlson Accardi在2月初提出了一个RFC patch set,提供了这个细粒度KASLR的概念实现。她指出了现有KASLR方案的3个弱点:

  • 对kernel施加的随机熵不够大。

  • 如果一个地址被泄露了,就可以利用这个offset来算初kernel中所有其他数据的地址。

  • 有许多种会暴露这个offset的信息泄露方式

所以,简单来说:“这组patch set会在加载的时候对各个函数更改加载地址,并且只会增加1秒钟的启动耗时。”

改动主要在两个方面。在编译kernel的时候,需要增加一个GCC option,来把各个函数放在它自己的.text p。在kernel加载的时候,刚解压缩好kernel,就可以利用relocation address来对这些text p进行重新洗牌。在kernel里面目前有一些存放地址的table,包括exception handling和kprobe等,不过她也有办法来处理:“绝大多数这种table都会触发relocation,稍微改一下就好。有些table对函数的顺序有要求的,这种就需要在更改之后排一下序。为了能修改这些table,我们在objcopy对symbol进行stripping的阶段会保留一些关键的symbol,用来今后对text segment进行洗牌时所用。”

第二处改动是在加载kernel到memory中的地方。启动流程会改为解析vmlinux ELF文件来提取一些关键的symbol,并搜集齐需要重新排序的.text.* p列表。这些函数的顺序就会被随机重排一下,然后更新相关的table:“需要更改现有的代码,不能只依赖加载地址所使用的固定偏移量,而是需要根据函数text p移到的位置而来的偏移量。这需要仔细检查各个地址来看他是不是需要做随机化处理。我们使用了bsearch来改善这个操作的性能。”

在debug这个概念性方案的时候,用了一个PRNG(伪随机数生成器),所以每次只要给它一个相同的随机数种子(seed),就可以每次都生成相同的函数排布顺序。Kees Cook提供了一个PRNG patch,有一些性能提升。不过Andy Lutomirski则不赞同使用这个新增的、未曾证实过的算法。他建议使用一个deterministic random bit generator (DRBG),例如ChaCha20这种。同样,Jason A. Donenfeld也担心这个随机数序列可能会在泄露几个函数地址之后就被推测出来,这样一来会让这个功能打了折扣。Cook也觉得使用ChaCha20是个比较好的主意。

这组patch set还移除了非root用户对/proc/kallsyms文件的访问权限,这个文件节点会列出所有kernel symbol的地址。目前kallsyms在非root用户读取它时,会对所有地址都返回0,不过symbol列出的顺序是按照kernel text中的顺序来排序的,这样就会出卖了我们随机排布过后的kernel函数地址,因此要关闭非root用户的访问权限。Cook指出,过去也曾经有人把kallsyms文件改成不可读的,当时曾经导致userspace的一些功能不太正常。建议最好是把symbol name按字母顺序排序,或者等等看是不是有人真的抱怨这一点。

Impacts

Accardi在一个VM虚拟机里面测量过这组patch对boot time的影响,看起来基本上会多耗1秒钟时间,对绝大多数应用场景来说这不算什么。系统正常运行期间的性能影响则很难评判。各种比较重要的kernel build速度的指标,基本上看起来性能都比只开了KASLR的相同kernel要慢1%左右。有些workload的表现更加差一些,其他的基本上都保持不变甚至有的还莫名变得更好了。性能还是跟workload所用到的代码流程有关,这方面今后可能可以做不少研究。此前就有文章通过优化函数的layout来优化某种workload的性能,见此https://research.fb.com/wp-content/uploads/2017/01/cgo2017-hfsort-final1.pdf

在vmlinux ELF文件里面增加了这些额外的用于支持细粒度KASLR的信息,导致它的size也增加了,不过影响更大的是需要增加boot heap size。对这些text p进行随机化排布,需要64MB的heap size,比起当前的方案要用到的大得多(现在bzip2需要4MB,其他解压缩方案只需要64KB)。增大的boot heap size会导致需要在kernel image里面增加更大的全部填0的区域来容纳这个heap。

Cook提出的一个patch也包含在Accardi的这组patch set之中,希望能有助于这个问题,不过最终看来这里的问题其实是kernel object里的p排布过程中的一个bug。Arvind Sankar指出他的1月份的patch set应该能解决这个问题。Cook也同意这个解决方案更加好。

Lutomirski认为在symbol name里面的排序机制开销有点大了。只要再增大一点memory的话,sort()调用里的swap函数中许多动作就都可以去除了:“除非你实在缺少memory,否则的话不要用像这里实现的swap函数。而应该是分配一组数组,就像[0, 1, 2, ...]这样,在swap的时候只要swap这些片段就好。接着可以用排好的list来变更真正的数据。这样实现之后,会对每个item只做一次非常耗时的swap操作,而不会对每一次swap动作都调用这种非常耗时的swap操作。”

Cook认为有些场景下可能会有需要牺牲速度来节省memory。目前这个方案里面用到的memoy的数量已经大大超过他的预期了(他的测试中看到需要58MB)。其中一个问题就是在解压缩kernel image的过程中调用的这版free()函数实际上并没有释放任何memory。不过Accardi认为目前额外增加的1s启动时间并不会阻碍那些想要使用这个保护的人,而那些追求启动时间最短的场景其实也不会想用这种细粒度的KASLR功能。

Security and alignment

在这组patch set的cover letter中,Accardi就分析了这组patch set的一些安全属性,通常人们认为所谓的信息泄露,都是需要能对系统进行本地访问的。不过CVE-2019-0688则演示了Windows环境中的一种远程地址泄露问题。这组patch set假设这种信息泄露会很常见,从而致力于让攻击者在拿到这些泄露信息之后也很难对系统进行攻击。对攻击者来说,所增加的难度主要取决于如下因素:“首先,最明显的是,你选择来随机化的函数的数量。比如说,这个方案不会对现有的.text p中的函数进行随机化,因为这些是汇编代码或者是我们专门为了性能原因而选择避免随机排布的函数。我们进行随机排布的p越少,随机熵和复杂度就越低。此外,因为一些对齐的需求(x86_64需要16bytes对齐),攻击者对地址进行猜测的bit数量也变少了,因为低位的bit都是一致的。”

Jann Horn指出Intel建议16-byte对齐是为了优化branch target,如果不符合这个对齐要求的话,可能会导致调用效率下降。Sankar认为目前的alignment要求对随机性影响不打,不过Lutomirski认为还有其他因素要考虑:“这里还是要考虑一个安全问题,如果攻击者确认了两个函数的位置,拿到两者之间的偏移量,那么就可以根据这个偏移量来猜测有哪些函数可以放在这个区域。我们应该使用padding(补全)来增加这种攻击的难度,比如使用一些ramdon padding。”

他还认为Intel处理器有个问题,无法处理某种跨越了cache-line边界的跳转指令。Peter Zijlstra看了一下erratum文档,确认其中有要求函数需要按照32-byte对齐。Cook认为需要对kernel整体进行一些改动来处理好这个问题。

目前对于细粒度KASLR的反馈都还是很正面的。没有人提出对于这个目标的反对意见,也没人提出对这个技术总体实现上的反对意见。应该算是对KASLR的一个很不错的增量修改。也能跟各种control-flow integrity (CFI)措施共存,毕竟它们也正在往upstream推。Accardi也说这个主意本身并不新奇,此前已经有许多关于此的研究了。比如OpenBSD使用了一个类似的机制来在启动时对kernel进行随机变化。当然,后续还是有很多工作要做,不过大概率来说今年应该会看到这个功能合入mainline的。

全文完

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值