我试图理解最近随着 Linux 4.0 进入主线而了解的一个新概念——“实时补丁”。
据说这是Linux内核的一个新功能增强。它最初是大约一年前由 Red Hat 和 Open SUSE 独立开发的。
我知道,任何功能开发/错误修复通常都是通过补丁在Linux内核中实现的,即,您为相关的Linux内核版本应用补丁,重新编译内核源代码并通过常规方法安装它$make;sudo make install
。
所谓的“实时修补”机制的有趣部分是,您不必重新编译并安装新的内核版本?我的意思是,您的 GRUB 不会显示较新内核版本的条目,对吧?因为您没有进行安装。
现在,这是我需要消化的一些严肃的概念。怎么可能?,如何实施?
Red Hat和Open SUSE分别使用Kpatch和kGraft来实现它。
我想尝试一个简单的内核模块,并使用 Kpatch 或 kGraft 之一来实现它。但是我有 Ubuntu 14.04 系统,有 Ubuntu 的替代品吗?
我对这个新概念最接近的理解是,您需要在新框架(如 ftrace)中编写和编译补丁。因此,您将把来自用户空间的 API/ABI 从“有缺陷的”内核模块重定向到您刚刚使用此补丁安装的较新的 API/ABI 实现(如何“仅”安装一个构建的补丁)在一个特殊的框架中?)。我在这儿吗?
如果任何一位 Linux 内核专家了解这一点,我很想听听您的意见,这个“实时补丁”到底是什么,以及如何创建实时补丁,然后系统的用户将如何安装这个补丁并验证它的功能(测试它)?
在理解这个概念的同时,我想知道如何编写这样的“实时补丁”?我还需要什么环境才能这样做?
答案1
如果内核不是完全重写(函数名称发生更改等,传递给函数的参数重新排序),您可以分析原始内核和修补后的内核的二进制文件,并查看哪些函数发生了更改。
然后,您覆盖已更改例程的开头,以跳转到已加载到内存中的例程的已更改版本。这是在没有其他进程运行时完成的。
维基百科上的文章克斯拼接以易于理解的方式更详细地解释了这一点。
您当然可以尝试编写一个补丁,并提出更小的补丁(更改几行机器代码,而不是完整的功能)。此类较小的补丁要求您小心地跳回原始例程,而不是仅仅从修补后的函数调用中返回。
与分析和修补内核二进制文件相比,修补 grub 菜单以获得新版本号很容易。该菜单仅是文本。但我们的想法是,无论如何,您在第一次启动后永远不会看到 grub 菜单。
这可能是 Red Hat 和 Open SuSE 中的一个新功能,但它并不是一年前发明的,例如 ksplice 早在 2008 年就开始修补正在运行的内核。修补内存中的程序(不一定是 Linux 内核)的概念是老很多。早在 1984 年,我自己就已经使用基于手动分析的内存中的程序修补(修补 6502 机器代码),当时我自己当然没有想到这样做。