当前位置:首页>Linux>linux驱动热补丁原理与bond双发arp热补丁示例

linux驱动热补丁原理与bond双发arp热补丁示例

  • 2026-10-11 07:52:13
linux驱动热补丁原理与bond双发arp热补丁示例

热补丁原理

1. 代码替换机制:Ftrace 与跳转指令

热补丁的核心技术基于 Ftrace(Function Tracer) 框架:

  • 跳转指令替换:利用 x86 架构下 call 指令(5 字节)或 ARM64 的 b 指令,在函数入口处插入跳转到新函数的指令
  • 运行时原子写入:通过 text_poke() 等接口在运行中安全地修改内核代码段(.text),通常需要内存页写权限临时开启
  • 旧函数保留:原始函数体保留,仅入口被"劫持",保证正在执行的旧函数实例能安全返回

2. 一致性模型:Klp 与 Kgraft

Linux 社区主要采用两种一致性保证策略:KLP (Kernel Live Patching) - 主线采用:

  • 停止点(Consistency Model):利用内核已有的 klp_update_patch_state() 机制,通过任务状态标志位跟踪
  • 原子切换:当所有 CPU 都经过安全点(如系统调用返回、中断返回)时,新代码路径对所有后续调用生效
  • 栈回溯检查:确保没有任务正在执行被补丁函数的旧版本(通过 walk_stack() 检查)Kgraft - SUSE 方案(历史):
  • 采用类似 RCU 的延迟释放机制,旧代码持续运行直到所有引用退出

3. 数据结构:Livepatch 模块

// 核心结构体structklp_func {void *old_func;      // 指向原函数void *new_func;      // 指向补丁函数char *old_name;      // 符号名(用于查找)structklp_object *obj;};structklp_patch {structklp_object *objs;structlist_headlist;bool enabled;// ...};

4. 加载与激活流程

  1. 模块加载:通过 insmod patch.ko 加载包含新函数的 ELF 模块
  2. 符号解析:klp_resolve_symbols() 解析旧函数地址(通过 kallsyms)
  3. 注册补丁:调用 klp_enable_patch() 注册到 livepatch 子系统
  4. 一致性等待:遍历所有任务,检查栈中是否包含被替换函数
  5. 原子激活:所有 CPU 同步后,通过 arch_klp_patch_func() 写入跳转指令
  6. 生效确认:后续调用直接进入新函数路径

5. 限制与边界

  • 非语义变更:只能修改函数实现,不能改变数据结构布局(结构体字段增减)
  • 无静态变量变更:不能修改全局/静态变量语义,因为旧模块仍在引用
  • 调用约定保持:新函数必须保持与原函数相同的 ABI(参数、返回值、调用约定)
  • 安全点依赖:需要内核配置 CONFIG_LIVEPATCH 和 CONFIG_DYNAMIC_FTRACE

热补丁制作工具

kpatch-build kpatch-build 是一款热补丁制作工具,可在不重启系统和中断业务的情况下对操作系统内核进行CVE和Bug修复。 支持架构: X86,ARM64 上游社区:https://github.com/dynup/kpatch![[Pasted image 20260508174701.png]]

准备工作

以Redhat系列linux为例

  1. 依赖准备 确保可以编译内核和驱动
yum install -y make gcc patch bison flex openssl-devel elfutils elfutils-devel dwarves bc perl
  1. 内核信息准备 下载kernel-debuginfo,kernel-devel,kernel source
  2. 安装kpatch-build 可以选择直接按照官方编译的rpm包,或自己编译
  • rpm安装yum install kpatch-build
  • 编译
wget https://gitee.com/anolis/kpatch-build/repository/archive/master.zip

解压v0.9.9.tar.gz

调用patch.sh脚本,把仓库中的patch打上源码

./patch.sh

进入kpatch-0.9.9目录下 如果你是需要使用kpatch core module加载(即kpatch.ko),设置BUILDMOD=yes

make BUILDMOD=yes && make BUILDMOD=yes install

如果不需要使用kpatch.ko,使用livepatch

make && make install

kpatch-build使用

kpatch-build -n kpatch-test  -s /root/hotfix/linux-4.19.91-26.4.an7 -c /root/hotfix/.config -v /root/hotfix/vmlinux -o /root/hotfix/output/ -dddddd -R  /root/hotfix/test-livepatch.patch 

其中:

-n 补丁名称-s:指向源代码目录-c: config文件-v: vmlinux文件-o: 产物输出目录test-livepatch.patch:补丁文件-d: 输出debug信息

制作oot hotfix

制作oot hotfix的过程与制作kernel hotfix的过程一致,只是输出参数区别

kpatch-build -s {path_to_kernel_source} -c {path_to_kernel_config} -v {path_to_kernel_vmlinux}  --oot-module-src {path_to_oot_module_source} --oot-module {path_to_oot_module_ko} {path_to_patch_file}

使用说明

热补丁中自带kpatch管理工具 加载热补丁:

kpatch load kpatch-test.ko

卸载热补丁:

kpatch unload kpatch-test.ko

热补丁列表:

kpatch list 

示例

linux低版本bond驱动新增双发arp功能

准备

  1. 安装kernel相关debuginfo包
  2. arp双发patch
--- bonding/bond_main.c 2026-05-01 01:07:34.956327587 -0400+++ bonding/bond_main.c 2026-05-01 01:11:01.920233936 -0400@@ -4614,6 +4614,8 @@        return slave; }+static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb,+                                      struct net_device *bond_dev); /* Use this Xmit function for 3AD as well as XOR modes. The current  * usable slave array is formed in the control path. The xmit function  * just calculates hash and sends the packet out.@@ -4625,6 +4627,10 @@        struct bond_up_slave *slaves;        struct slave *slave;+       if ( skb->protocol == htons(ETH_P_ARP) ) {+               return bond_xmit_broadcast(skb, dev);+       }+        slaves = rcu_dereference(bond->usable_slaves);        slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves);        if (likely(slave))
  1. 编译脚本build.sh
path_to_kernel_source=/lib/modules/4.18.0-372.9.1.el8.x86_64/buildpath_to_kernel_config=/boot/config-4.18.0-372.9.1.el8.x86_64path_to_kernel_vmlinux=/usr/lib/debug/lib/modules/4.18.0-372.9.1.el8.x86_64/vmlinuxpath_to_oot_module_source=/root/bondingorigpath_to_oot_module_ko=/root/bonding.kopath_to_patch_file=/root/arp.patchkpatch-build -s ${path_to_kernel_source} -c ${path_to_kernel_config} -v ${path_to_kernel_vmlinux}  --oot-module-src ${path_to_oot_module_source} --oot-module ${path_to_oot_module_ko} ${path_to_patch_file} -t ''
  1. 编译
sh build.sh
  1. 安装
kpatch load livepatch-arp.ko

注意

热补丁加载时,需要确保所有CPU都完成函数替换,所以如果有其他进程长时间占用CPU,可能导致加载热补丁失败,需要其他进程释放CPU后才能成功。

最新文章

随机文章