I want to modify the parameters passed to a kernel function through livepatches, but without changing the function's logic. Referring to the livepatch sample, assume that the original function is func_old(int a) and the new function is func_new(int a).
If I call the old function directly in the new function, like this:
void func_new(int a){
int b = a+1;
func_old(b);
}
Will infinite recursive calls occur? How should this situation be avoided?
func_old is not visible to the patch and will raise an error of 'implicit declaration of function'. How could this be avoided?
I tried with the following method, but the system hang after I call cat /proc/cmdline.
#include <linux/seq_file.h>
static int (*real_cmdline_proc_show)(struct seq_file *m, void *v);
static int fh_cmdline_proc_show(struct seq_file *m, void *v)
{
int ret;
seq_printf(m, "%s\n", "this has been ftrace hooked");
ret = real_cmdline_proc_show(m, v);
pr_debug("cmdline_proc_show() returns: %ld\n", ret);
return ret;
}
static struct klp_func funcs[] = {
{
.old_name = "cmdline_proc_show",
.new_func = fh_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,
};
static int livepatch_init(void)
{
int result = klp_enable_patch(&patch);
int (*real_cmdline_proc_show)(struct seq_file *m, void *v) = funcs[0].old_func;
return result
}
static void livepatch_exit(void)
{
}
module_init(livepatch_init);
module_exit(livepatch_exit);
MODULE_LICENSE("GPL");
MODULE_INFO(livepatch, "Y");
It is possible to call a non-exported and private function, but you might need some extra tools.
In the current kernel implementation, you can call the original function, e.x.
cmdline_proc_show, at runtime with some special ELF relocations and symbols. You can find more details here: https://docs.kernel.org/livepatch/module-elf-format.htmlTo generate these relocations and symbols is not trivial. You might need to have some tools to perform this ELF editing.
One of the existing tool is kpatch (https://github.com/dynup/kpatch).
It would NOT help you to implement code as
To implement a similar fix, you need to re-write the function as
kpatch will help you handle the rest of the relocation/symbol work.
Another example from kpatch: https://github.com/dynup/kpatch/blob/master/examples/cmdline-string.patch