7

Faster Reference Count Overflow Protection

 3 years ago
source link: https://kernel.taobao.org/2017/08/Faster-reference-count-overflow-protection/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Aug 1, 2017

Faster Reference Count Overflow Protection

https://lwn.net/Articles/728675/

提高系统安全性通常意味着对编程便捷性和性能代价妥协。令安全开发者沮丧的是他们经常发现对这些代价容忍度是很低的。而防止引用计数溢出这个特性就遇到了这个问题,这也导致了它迟迟没有被广泛接受。现在,防止引用计数溢出特性的性能问题已经找到了一种解决方案,这清除了它推广到整个内核代码的障碍。

引用计数溢出通常出现在编程错误。比如说,代码在增加引用计数后,经常会在处理错误路径中忘了去减小计数。攻击者可以利用这种错误重复去增加一个引用计数,直到该引用计数溢出,此时该对象被认为是未使用的而被释放,但实际上仍在使用。这产生的“释放后使用”(use-afer-free)行为是可以被利用,从而造成危害系统的行为。

防止计数溢出的保护代码已经在内核中存在已久。从 PaX/grsecurity 补丁集就开始了,但一开始的手段是基于使用 atomic_t 类型,现在已经变化了。下一步打算引入新的类型 refcount_t,保护代码也会添加到这个类型中去。这个类型在内核 4.11 的合并窗口中被加入,许多内核子系统已ç»修改相关代码去使用这个类型,但是许多网络子系统的开发者不愿意使用它,因为会引发性能损失。

网络层提交的补丁经常会遇到性能问题,但上述性能问题不仅仅出现在网络层。Andrew Morton æ近在进程间通信子系统迁移到 refcount_t 类型的过程中抱怨 —— 他认为在“简单,安全,老,严格测试的代码”中添加安全检查而造成运行缓慢,这是没有意义的。现在会出现这样的问题:即使计数溢出保护代码在内核中被使用了,它们也会被发行人员因性能问题而关闭掉

系统安全开发的一个真理就是,关闭(或者是从未实现)保护措施将根本无法抵御攻击者。另一个真理是,“安å¨,老,严格测试的代码”可能仅仅只是“老的代码”,正如 Ingo Molnar 指出的:

当代码在基于_现存的,合理的参数_使用时,它们是没有问题的。但是一旦有人用一个不合理、没人使用过的参数å现一个十年前的老问题时,它们就会基于这个问题开发漏洞

想要真正保护内核防止引用计数溢出,需要让检查变得普遍。也就是说,要么说服开发者接受检查带来的性能损耗,要么找到一种方法将性能损耗降低到一种可以接受的程度。显然,如果损耗能被降低,后者是一种最少阻力的实现路径。

在 Kees Cook 的“快速引用计数保护”补丁集中,他发现了一种确实有效的解决方案。补丁通过一个指令操作现存的(高度优化)atomic_t 实现,该指令会捕捉引用计数变成负数(也刚好是计数器溢出)的场景。这个指令非常容易通过处理器的分支预测逻辑来正确地猜测下一步,所以它æ§行性能非常好,如补丁集附带的微基准结果显示,标准的 atomic_t 实现使用了 822.49 亿个指令周期;新的 refcount_t 代码使用了 822.11 亿个指令周期,除去边缘误差两者是一致的。而作为对比,原来的 refcount_t 实现则需要使用 1448 亿个指令周期来运行测试。

目前,该补丁只适用与x86架构。当其他人开始着手做相关架构的移植时,只要将各自架构的代码进行组装即可实现。在主要的非x86架æ的移植中,该工作也没有明显的技术障碍

相对原先完整的 refcount_t 实现,这个变化有一个不再检查从0增加1情况的代价。一个对象的引用数当降低到0时,这个对象一般会被释放;随后一个计数å¢加操作意味着这个将被释放的引用对象仍在被使用。很明显,这是一个有必要捕捉的场景,但是没有人能在不增加任何额外检查代码的情况下解决该问题。Cook 在这个补丁中声明,在新的 refcount_t 中能在大多数场景中捕捉到溢出行为,并引用了两个漏洞(CVE-2014-2851 和 CVE-2016-0728),即使有检查代码仍没有阻止漏洞执行。

仍有许多开发者对 refcount_t 类型保持着冷漠的态度;比如说来自 Eric Biederman 的抱怨 (以及 Cook 的回应)。剩下的反对意见主要基于几个论点:(1)refcount_t 并不能修复所有引用技术相关的问题 (2)使用这个类型暗示着这些代码可能存在问题,而着使一些开发è自尊心受到损害。但是,随着性能问题被解决,其他抱怨将不会阻碍引用计数强化内核的进程。这对关心安全的人来说是最好的消息。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK