2 Star 2 Fork 0

laokz / klpmake

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.zh.md 4.47 KB
一键复制 编辑 原始数据 按行查看 历史
laokz 提交于 2024-01-11 18:50 . add DWARF evaluation tools

KLPMAKE

Inspired by KPATCH @ https://github.com/dynup/kpatch. Many thanks!

Klpmake 是Linux内核热补丁制作工具,它调用编译工具链,将用户的补丁文件生成为“部分链接”的目标文件,对其中的Livepatch Symbols -- non-exported global symbols and non-included local symbols进行修正,最终生成符合Livepatch module ELF format的内核模块。

Klpmake以内核samples/livepatch/livepatch-sample.c为模板,通过.patch文件自动生成补丁模块源码。再通过内核和模块DWARF信息及/proc/kallsyms/proc/modules,可靠解析定位Livepatch Symbols。制作时不编译内核,不深入hacking ELF格式,也基本架构无关。

Klpmake小、简单、快,支持对内核及已加载的模块打补丁。

当前主要针对的是openEuler操作系统。

用法

软件依赖及编译

软件依赖libdwarf(>=0.8.0)、libclang、elfutils-libelf(gelf)、bash及一些coreutils工具。运行时需要内核/模块源码、debuginfo文件(DWARF4格式)。热补丁模块制作过程与常规模块基本相同,需要内核的编译构建基础设施。一些依赖库的安装命令:

sudo dnf install clang-libs clang-devel libdwarf-devel elfutils-libelf-devel bash

不同的发行版,软件安装的目录可能不同。在编译klpmake前请检查并修改当前还很简陋的config.h和Makefile内容,然后:

make

Klpmake由klpmake(主入口)、klpsrc、fixklp三个可执行文件组成。

运行

创建工作目录,目录名将作为热补丁的模块名;将补丁文件放到工作目录下,执行:

sudo klpmake-dir/klpmake -s source-tree-root -b debuginfo-tree-root

source-tree-root是源码树根目录,debuginfo-tree-root是包含debuginfo文件的根目录,如vmlinux、*.ko.debug等。

建议分步执行klpmake,这样可以检查确认每步的结果是否正确是否符合预期,并可以根据需要增加hook功能等。用法见klpmake的Usage。

生成的文件

  • livepatch.c 补丁模块主文件
  • *.c 补丁模块其它文件
  • Makefile 补丁模块Makefile,以上文件由klpsrc生成
  • *.ko 最终生成的补丁模块
  • _klpsrc.conf 补丁基本信息,klpmake生成,klpsrc使用
  • _klpmake.syms KLPSYMs位置信息,klpsrc生成,fixklp使用
  • *.c.patched 打补丁后的源码文件
  • *.ko.patial “部分链接”的补丁,内核编译工具生成,fixklp使用

示例

example

局限

  • 查找源码所属模块时,依赖同目录下Makefile严格的代码模式匹配(klpmake)
  • 查找修改的函数时,依赖严格的.patch代码模式匹配(klpmake)
  • 只支持一个.patch文件(klpmake、klpsrc)
  • 不支持检测基于ftrace livepatch机制的函数打补丁条件(klpmake、klpsrc)
  • 定义在头文件或函数内的static变量均被视为新变量(klpsrc)
  • 不支持对可变参数的函数打补丁(klpsrc)
  • 内核/模块二进制必须有DWARF4信息,有.debug_info和,.debug_aranges或.debug_ranges节(klpsrc)
  • 不支持同一源文件中的static变量重名或与extern变量重名(klpsrc)
  • 不支持不同源文件的non-included static符号、被补丁函数重名(klpsrc、fixklp)
  • 未考虑KSYM_NAME_LEN(512)符号名长度限制(klpsrc、fixklp)
关于DWARF信息

社区有对DWARF信息可靠性的担心,这里列出klpmake用到的:

  • 定位函数符号:DW_TAG_compile_unit的DW_AT_name、DW_AT_low_pc、DW_AT_high_pc、DW_AT_ranges
  • 定位函数符号(当前仅作info用):DW_TAG_subprogram的DW_AT_name、DW_AT_low_pc、DW_AT_decl_line
  • 定位变量符号:DW_TAG_variable的DW_AT_name、DW_AT_location、DW_AT_decl_line(当前仅作info用)

用tools目录下的工具,比对vmlinux中的DWARF和kallsyms中的变量名字、地址:

架构 kallsyms数量(非t/T) DWARF数量 DWARF不匹配kallsyms数量 kallsyms去掉.xxx后
x86-64 49919 28989 5846 305
riscv64 53100 44225 5710 25
aarch64 46259 25680 5202 47

因为函数内定义的static变量名字会后缀.123,因此单纯从数量上看,不匹配率基本小于1%。具体分析,DWARF会生成一些弱符号的地址,,

工具是在riscv64平台上开发和测试的,刚刚迈出一小步...

非常期待你的试用与反馈!非常欢迎hacker来指点贡献!

C
1
https://gitee.com/laokz/klpmake.git
git@gitee.com:laokz/klpmake.git
laokz
klpmake
klpmake
master

搜索帮助