Kernel Livepatching示例
Posted rtoax
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kernel Livepatching示例相关的知识,希望对你有一定的参考价值。
1. 测试代码
源码:linux-5.10.13/samples/livepatch
2. 示例1:livepatch-sample.c
我们只看一个示例:livepatch-sample.c,它修改内核的命令行查看结果,当前的查看结果为:
$ cat /proc/cmdline
BOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18.0-30501.10.2.el8.x86_64 root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet
当执行上面的命令时,内核中将调用函数cmdline_proc_show
,可以用bpftrace追踪:
$ sudo bpftrace -e 'kprobe:cmdline_proc_show {printf("call cmdline_proc_show.\\n");}'
Attaching 1 probe...
call cmdline_proc_show.
我们将对函数cmdline_proc_show
打热补丁,所以我们需要自己实现热补丁函数:
#include <linux/seq_file.h>
static int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s\\n", "this has been live patched");
return 0;
}
然后静态定义补丁结构:
static struct klp_func funcs[] = {
{
.old_name = "cmdline_proc_show",
.new_func = livepatch_cmdline_proc_show,
}, { }
};
static struct klp_object objs[] = {
{
/* name being NULL means vmlinux */
.funcs = funcs,
}, { }
};
static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
};
接着,在模块初始化中调用klp_enable_patch(&patch);
使能这个补丁即可。
2.1. 编译与加载补丁
操作如下:
$ make
[...]
$ sudo insmod livepatch-sample.ko
同样,这个步骤可以用bpftrace追踪:
sudo bpftrace -e 'kprobe:klp_enable_patch {printf("call klp_enable_patch.\\n");}'
2.2. 测试
再次查看/proc/cmdline
文件:
$ cat /proc/cmdline
this has been live patched
2.3. 卸载补丁
倘若我们直接卸载模块,将会失败:
$ sudo rmmod livepatch-sample.ko
rmmod: ERROR: Module livepatch_sample is in use
应该先将补丁去使能,这需要在 sysfs下操作:
# pwd
/sys/kernel/livepatch
# tree -a
.
└── livepatch_sample
├── enabled
├── force
├── transition
└── vmlinux
├── cmdline_proc_show,1
└── loadavg_proc_show,1
4 directories, 3 files
将enabled
的值修改为0即可:
# echo 0 > livepatch_sample/enabled
# tree -a
.
0 directories, 0 files
然后再卸载模块:
$ sudo rmmod livepatch-sample.ko
3. 示例2:
Copyright (C) CESTC Com.
以上是关于Kernel Livepatching示例的主要内容,如果未能解决你的问题,请参考以下文章
"arch/arm/kernel/head.S"里面一点片段的理解