1 Star 0 Fork 36

HuBin95 / kpatch

forked from src-openEuler / kpatch 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

openEuler内核热补丁使用指南

支持操作系统:

openEuler 20.03 LTS及以上版本

openEuler社区已经验证支持内核热补丁的架构:

  • x86_64
  • arm64
  • ppc64le
  • s390
  • risc-v

上游社区:

https://github.com/dynup/kpatch

内核热补丁说明

内核热补丁一般用于在不重启机器的前提下在线修复内核函数问题。

常用场景:

  • 在线修复内核漏洞(CVE、bugfix)
  • 在线修复驱动漏洞(bugfix)
  • 内核问题定位
  • 开发调试

注1:内核热补丁加载激活之后,若机器重启,则热补丁失效,需重新加载激活才能继续生效。

若需要机器重启后自动加载激活热补丁,可编写启动执行脚本,在脚本里加载激活指定的热补丁。

注2:热补丁存在一定的约束限制,部分场景下无法做补丁,详见最后一节。

环境准备

安装依赖软件包

yum install -y make gcc patch bison flex openssl-devel kpatch kpatch-runtime elfutils-libelf-devel

安装当前内核源码和开发包

yum install -y kernel-source-`uname -r` kernel-debuginfo-`uname -r` kernel-devel-`uname -r`

进入热补丁制作目录并准备环境

cd /opt/patch_workspace
rm -rf kernel-source .config
ln -s /usr/src/linux-`uname -r`/ kernel-source
ln -s /usr/src/linux-`uname -r`/.config .config
ln -s /usr/lib/debug/lib/modules/`uname -r`/vmlinux vmlinux

制作内核热补丁

支持两种方式制作内核热补丁

方法1:直接修改源代码的方式

进入内核源码目录(下面以修改fs/proc/cmdline.c文件为例)

cd kernel-source
cd fs/proc/
cp cmdline.c cmdline.c.new

此处cp操作的后缀.new在后面执行make_hotpatch时会用到

修改cmdline.c.new中的函数

开始制作热补丁

cd /opt/patch_workspace/
./make_hotpatch -d .new -i cmdline
参数 说明
-d 前面cp操作时的唯一后缀名
-i 补丁ID,可包括字母和数字

方法2:通过patch文件的方式

cd /opt/patch_workspace/
./make_hotpatch -i cmdline -p cmdline.patch
参数 说明
-i 补丁ID,可包括字母和数字
-p patch文件路径(patch文件必须支持在kernel-source路径下通过patch -p1的方式修改源码)

补丁制作完成,补丁文件以压缩包的格式存放于/opt/patch_workspace/hotpatch目录下

制作第三方模块热补丁

支持两种方式制作第三方模块热补丁

方法1:直接修改源代码的方式

进入模块源码目录(下面以https://gitee.com/openeuler/prefetch_tuning模块为例)

git clone https://gitee.com/openeuler/prefetch_tuning
cd prefetch_tuning
cp prefetch_mod.c prefetch_mod.c.new

此处cp操作的后缀.new在后面执行make_hotpatch时会用到

修改prefetch_mod.c.new中的函数

cd /opt/patch_workspace/
./make_hotpatch -d .new -i testmod -m `pwd`/prefetch_tuning/
参数 说明
-d 前面cp操作时的唯一后缀名
-i 补丁ID,可包括字母和数字
-m 第三方模块源码路径
-f 可选,当第三方模块Makefile不在-m指定的源码目录下时,通过该参数指定Makefile的绝对路径

方法2:通过patch文件的方式

cd /opt/patch_workspace/
./make_hotpatch -i testmod -m `pwd`/prefetch_tuning/ -p testmod.patch
参数 说明
-i 补丁ID,可包括字母和数字
-m 第三方模块源码路径
-p patch文件路径(patch文件必须支持在-m参数指定的路径下通过patch -p1的方式修改源码)
-f 可选,当第三方模块Makefile不在-m指定的源码目录下时,通过该参数指定Makefile的绝对路径

第三方模块补丁补丁制作完成,补丁文件以压缩包的格式存放于/opt/patch_workspace/hotpatch目录下

管理热补丁

加载热补丁

livepatch -l klp_cmdline.tar.gz

激活热补丁

livepatch -a cmdline

此时热补丁已生效,缺陷函数已被修复。

回退热补丁

livepatch -d cmdline

卸载热补丁

livepatch -r cmdline

编译更新补丁工具

yum install -y git rpm-build elfutils-libelf-devel gdb-headless
git clone https://gitee.com/src-openeuler/kpatch.git
mkdir -p ~/rpmbuild/SOURCES/
/bin/cp kpatch/* ~/rpmbuild/SOURCES/
rpmbuild -ba kpatch/kpatch.spec
rpm -Uvh ~/rpmbuild/RPMS/`arch`/kpatch*.rpm
rpm -Uvh ~/rpmbuild/RPMS/noarch/kpatch*.rpm

热补丁约束限制

不支持的函数修改行为

  • 不支持修改函数参数或返回值类型或个数。
  • 不支持删除函数。
  • 不支持修改数据结构成员(热补丁原理是做函数替换)。

不支持的文件修改行为

  • 不支持修改汇编文件。
  • 不支持修改头文件。
  • 不支持修改非C语言编写的文件。

不支持的变量修改行为

  • 不允许删除全局变量或函数内部静态局部变量。
  • 不支持修改全局变量或静态局部变量初始值。
  • 不支持新增同名静态局部变量。
  • 不支持修改多个同名静态局部变量的引用顺序。

不支持的函数类型

  • 不支持对初始化函数打补丁(初始化函数只执行一次,补丁函数执行不到)。

  • 不支持对死循环、不退出函数打补丁(旧函数不退出调用栈,没有机会调用新函数)。

  • 不允许对NMI中断的处理函数打补丁( stop machine无法stop住NMI中断处理流程,补丁无法保证对该类函数打补丁的一致性和安全性)。

  • 不支持对修改前后内敛情况发生变化的函数打补丁。

  • 不支持编译器生成的函数名称在修改前后发生变化的函数打补丁,例如修改前编译器生成的函数名为“ do_oops_enter_exit.part.0”,修改后编译器生成的函数名为“ do_oops_enter_exit”。

  • 不支持对arm64架构下长度小于4条指令的超小函数打补丁。(这种情况可以通过对外围函数打补丁来解决)

  • 不支持对启用ftrace、 kprobe等修改指令机制的函数打补丁。(打热补丁会使被修改函数的ftrace/kprobe机制失效)

  • 不支持对以下idle进程相关函数打补丁:

    • call_cpuidle
    • cpuidle_idle_call
    • do_idle
  • 不支持对包含以下弱符号的函数打补丁。

    • kallsyms_addresses
    • kallsyms_num_syms
    • kallsyms_names
    • kallsyms_markers
    • kallsyms_token_table
    • kallsyms_token_index
    • kallsyms_offsets
  • 不支持对包含下列范围之外的其他代码段的函数打补丁:

    • .text
    • __bug_table
    • .fixup
    • __ex_table
    • __jump_table
    • .smp_locks
    • .parainstructions
    • .altinstructions
  • 不支持在 .altinstructions 段中修改 ALTINSTR_ENTRY_CB 类型 alt_instr 的函数打补丁。例如 arm64 架构下 kvm 模块中的 kern_hyp_va 函数。

空文件

简介

暂无描述 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/hubin95/kpatch.git
git@gitee.com:hubin95/kpatch.git
hubin95
kpatch
kpatch
master

搜索帮助

14c37bed 8189591 565d56ea 8189591