一些背景
之所以说只是个 infrastructure, 是因为它只实现了热补丁的策略(如何做下文会介绍),而在一个运行中系统中打热补丁前后如何保证一致性的机制, 主线内核仍然不支持。 保持一致性是 Live Patching 的核心和关键所在。 试想,在一个循环中,如果实时补丁了一个在循环中调用的函数, 如果无法保证该函数版本的一致性,那不可避免地很可能遇到意外的情况,甚至是系统 crash。
事实上, Live Patching 是两大 Linux 发行版商 Red Hat 和 SuSE 去年(2014)开始主推进入内核主线的功能, 并都拿出了各自的解决方案, 即 kPatch 和 kGraft, 这两种方案都有各自解决一致性保证的解决方法:
kPatch 的做法是在热补丁时, 调用 stop_machine() 接口把机器停住,然后检查每个线程栈, 看要补丁的函数有无在运行,若没有,则可安全打补丁若有,则退出。然后再继续恢复机器运行。
kGraft 的做法是运用双宇宙模型,即维护另一份要修改函数的版本,每个线程都会在安全的时候切换到新版本上,这个安全的地方可以是系统调用返回的时候,因为此时不在内核态,可以安全修补。这其实是借鉴了内核中的同步机制 RCU(Read Copy Update) 的做法。
这两种方法都各有利弊,对两种方案的取舍要涉及很多细节性的东西 ,所以各方要讨论一个能很好支持两种方案的优点的方案。4.0 中 算是基础性工作, 它实现了热补丁的功能, 但一致性的解决方案还要等这两家之后基于此工作之上的解决方案。所以目前该功能只支持一些 trivial 的补丁,如不改变数据结构,不改变函数的返回值语义, 等。但这些也足以应付目前很多安全性补丁,很多 CVE 的 fix 就是加一两行 sanity check 而已。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)