kpatch
10 Mar 2017Kpatch是Redhat的一个内核热补丁框架,主要用于修复内核安全漏洞和稳定性bug,不能用于大的内核版本升级。另外两个类似的项目是Oracle的Ksplice和SUSE的kGraft。
Kpatch
Kpatch是Redhat的一个内核热补丁框架,主要用于修复内核安全漏洞和稳定性bug,不能用于大的内核版本升级。另外两个类似的项目是Oracle的Ksplice和SUSE的kGraft。
限制:
- 数据结构变化、边界情况无法处理
- stop_machine()延时1-40ms
快速使用
- 安装依赖
# yum install rpmdevtools pesign yum-utils openssl wget numactl-devel
- 编译kpatch和kpatch-build
# git clone https://github.com/dynup/kpatch # cd kpatch/ # make; make install
- 测试补丁
# cat kpatch-meminfo.patch diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index ade4e42..97252cc 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -131,7 +131,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) "Committed_AS: %8lu kB\n" "VmallocTotal: %8lu kB\n" "VmallocUsed: %8lu kB\n" - "VmallocChunk: %8lu kB\n" + "VMALLOCChunk: %8lu kB\n" #ifdef CONFIG_MEMORY_FAILURE "HardwareCorrupted: %5lu kB\n" #endif
- 编译模块
包括获取源码、测试补丁、读取特殊段数据、编译原始内核、
# kpatch-build -s ~/rpmbuild/BUILD/kernel-3.10.0-327.28.3.el7/linux-3.10.0-327.28.3.el7.x86_64/ -v /usr/lib/debug/usr/lib/modules/3.10.0-327.28.3.el7.x86_64/vmlinux kpatch-meminfo.patch Using source directory at /root/rpmbuild/BUILD/kernel-3.10.0-327.28.3.el7/linux-3.10.0-327.28.3.el7.x86_64 Testing patch file checking file fs/proc/meminfo.c Reading special section data Building original kernel Building patched kernel Extracting new and modified ELF sections meminfo.o: changed function: meminfo_proc_show Patched objects: vmlinux Building patch module: kpatch-kpatch-meminfo.ko SUCCESS
- 加载补丁模块
# kpatch replace kpatch-kpatch-meminfo.ko loading core module: /usr/local/lib/kpatch/3.10.0-327.28.3.el7.x86_64/kpatch.ko loading patch module: kpatch-kpatch-meminfo.ko
- 检查结果
# kpatch list # grep -i chunk /proc/meminfo VMALLOCChunk: 34359337092 kB
基本原理
kpatch包括编译补丁生成模块的kpatch-build和加载补丁模块的kpatch两个组件。
内涵打补丁步骤:
- 将新函数加载到内存
- 将新函数链接到内核,需要允许访问未导出的内核符号
- 安全检查(Active Safeness Check)
- 防止新旧函数同时运行
- stop_machine()和栈检查
- 使用ftrace打补丁
引用计数器
切换到新函数的时机,由引用计数器(refcount)控制。在热补丁期间允许函数继续被调用,但增加一个原子引用计数器,函数入口处引用计数增加,函数退出时计数减一。当引用计数为0时,更新所有函数路径。函数进入或退出通过kretprobe hook。
安全性检查
在上下文切换时执行运行安全性检查(Active Safeness Check),通过kprobe hook上下文切换。 两阶段检查:
- 检查休眠的任务。
- 检查运行中的任务。